Guillermo Rodas
Google Developer Expert in Web Technologies, Community Organizer, and Online Teacher.
@glrodasz
INTRODUCTION TO
TESTING
Google Developer Expert in Web Technologies
Community Organizer and Online Teacher
https://guillermorodas.com
@glrodasz
You can Google me as well.
Static Testing
Unit Testing
Structural Testing
Interaction Testing
Integration Testing
Visual Testing
End to End Testing
No too much code will be shown.
Warning
Static Testing, a software testing technique in which the software is tested without executing the code.
ESLint
(A little bit of black-box testing)
What is the difference between black-box and white-box testing?
function foo( , , ) {
return
}
describe('when , , '){
it('should return '){
result = foo( , , )
expect(result).equal( )
}
}
result
result
function foo( , , ) {
return
}
describe('when , , '){
it('should return '){
result = foo( , , )
expect(result).equal( )
}
}
result
result
function foo( , , ) {
return
}
describe('when , , '){
it('should return '){
result = foo( , , )
expect(result).equal( )
}
}
result
result
(Mock object)
An object under test may have dependencies on other (complex) objects.
To isolate the behavior of the object you want to replace the other objects by mocks that simulate the behavior of the real objects.
function foo( , , ) {
return
}
= bar( , , )
import bar from 'bar'
🙈
Monkey patching is a technique to add, modify, or suppress the default behavior of a piece of code at runtime without changing its original source code.
function foo( , , ) {
return
}
= bar( , , )
bar = () =>
import bar from 'bar'
🐒
💉
In software engineering, dependency injection is a technique in which an object receives other objects that it depends on.
function foo( , , , _bar) {
return
}
= _bar( , , )
foo( , , , bar);
import bar from 'bar'
bar
describe('when , , '){
it('should return '){
result = foo( , , ,bar)
expect(result).equal( )
}
}
result
result
bar = () =>
bar
TEST STUB
(Method stub)
A stub may simulate the behavior of existing code or be a temporary substitute for yet-to-be-developed code.
What is the difference between stubs and 🕵️♀️ spies in testing?
function foo( , , ) {
}
bar( , , )
import bar from 'bar'
import foobar from 'foobar'
foobar( )
foobar( )
describe('when , , and '){ it('should call the methods'){ foo( , , ) bar.calledWith( , , ) foobar.calledWith( ).firstime() foobar.calledWith( ).secondTime() } }
bar = stub()
foobar = stub()
🐒
🐒
import stub from 'awesome-stub-library'
* FLOW TESTING
(A little bit of white-box testing)
White-box testing is a method of software testing that tests internal structures or workings of an application, as opposed to its functionality (i.e. black-box testing).
function foo( , , ) {
if ( ) {
return
} else if ( && ) {
return
}
return
}
describe('when '){
it('should return '){}
}
describe('when and '){
it('should return '){}
}
describe('when none'){
it('should return '){}
}
Structural testing is the type of testing carried out to test the structure of code, sometimes is also called white-box testing.
function Foo( , , ) { if( ) { return h`<span> </span>` } if ( ) { return h`<i><b> </b></i>` } return h`<ul> ${ .map( => h`<li> </li>`)} </ul>` }
import h from 'awesome-html-render'
describe('when '){
it('should render'){
result = Foo( )
expect(result.span.length)
}
}
describe('when '){
it('should render'){
result = Foo( )
expect(result.i.length)
expect(result.b.length) } }
describe('when '){
it('should render'){
result = Foo( )
expect(result.ul.length)
expect(result.div.length === .length)
}
}
describe('when '){
it('should render'){
expect(Foo( )).toMatchSnapshot()
}
}
expect(Foo( )).toMatchSnapshot()
Sometimes you need to test how a component changes in response to user interaction.
function Foo( , handleClick, handleChange) {
state( + )
effect( , handleChange)
return h`<button onClick={handleClick} />`
}
import h from 'awesome-html-render'
import {state, effect} from '🏴☠️'
describe('when click'){ it('should call handleClick'){ Foo( , handleClick, handleChange) Foo.simulate('click') handleClick.called() } }
handleClick = stub()
handleChange = () => {}
import stub from 'awesome-stub-library'
describe('when change'){ it('should call handleChange'){ Foo( , handleClick, handleChange) Foo.setProp( ) handleChange.called() } }
handleClick = () => {}
handleChange = stub()
import stub from 'awesome-stub-library'
describe('when change'){ it('should update state'){ Foo( , handleClick, handleChange) Foo.setProp( )
Foo.state === } }
handleClick = () => {}
handleChange = () => {}
Integration tests strike a great balance on the trade-offs between confidence and speed/expense. This is why it's advisable to spend most (not all, mind you) of your effort there.
function foo( , , ) {
= +
= +
return bar( , )
}
import bar from './bar'
describe('when , , '){
it('should return '){
result = foo( , , )
expect(result).equal( )
}
}
result
result
function Foo( , onAuthorize) {
handleAuthorize = once(onAuthorize) return h`<Bar t={ } onClick={handleAuthorize}> Authorize </Bar>` }
import Bar from './Bar'
import once from 'awesome-once'
describe('when click'){ it('should call handleClick'){ Foo( , onAuthorize) Foo.find(<Bar>)simulate('click')
Foo.find(<Bar>)simulate('click') onAuthorize.calledOnce() } }
onAuthorize = stub()
import stub from 'awesome-stub-library'
(or anything that automates tests)
fixture `Test` .page `https://test.html`;
test('Testing', async t => {
const input = Selector('#input');
const alert = Selector('#alert');
await t.typeText(input, 'This is pretty cool!')
.pressKey('#enter')
.expect(alert.innerText)
.contains('No special characters allowed.');
});
import { Selector } from 'e2e-tool'
await t.typeText(input, 'This is pretty cool!')
.pressKey('#enter')
.expect(alert.innerText)
.contains('No special characters allowed.');
Interactive Testing with the Page
2 UNIT TESTS
0 INTEGRATION TEST
Visual testing is the automated process of detecting and reviewing visual UI changes. Teams are replacing manual testing with automation to ensure their websites and applications always look exactly as intended.
Screenshots and Videos
fixture `Test` .page `https://test.html`;
test('Testing', async t => {
const input = Selector('#input');
await t.typeText(input, 'This is pretty cool!')
.pressKey('#enter')
.takeScreenshot();
});
import { Selector } from 'testcafe'
.takeScreenshot();
Puppeteer is a Node library which provides a high-level API to control Chrome or Chromium over the DevTools Protocol.
Puppeteer runs headless by default, but can be configured to run full (non-headless) Chrome or Chromium.
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://example.com');
await page.screenshot({path: 'example.png'});
await browser.close();
})();
await page.screenshot({path: 'example.png'});
Puppeteer Recorder
Visual Tests is an opportunity to check visual bugs in specific browsers.
End to end testing (E2E testing) refers to a software testing method that involves testing an application’s workflow from beginning to end.
This method basically aims to replicate real user scenarios so that the system can be validated for integration and data integrity.
Selenium is a free (open-source) automated testing framework used to validate web applications across different browsers and platforms.
You can use multiple programming languages like Java, C#, Python etc to create Selenium Test Scripts. Testing done using the Selenium tool is usually referred to as Selenium Testing.
Selenium Webdriver is an open-source collection of APIs which is used for testing web applications.
It mainly supports browsers like Firefox, Chrome, Safari and Internet Explorer. It also permits you to execute cross-browser testing.
Selenium WebDriver
Web Driver API
WebDriver is a general purpose library for automating web browsers. It was started as part of the Selenium project, which is a popular and comprehensive set of tools for browser automation, initially written for Java but now with support for most programming languages.
End to End Testing
we wanted to simplify setting up the test environment.
To start with Selenium, you need to install the WebDriver client for the desired programming language and the appropriate drivers for each browser you're going to test in.
Write tests. Not too many. Mostly integration.
By Guillermo Rodas
An introduction guide about how to test in JavaScript
Google Developer Expert in Web Technologies, Community Organizer, and Online Teacher.