@glrodasz

INTRODUCTION TO
TESTING

Guillermo Rodas

Google Developer Expert in Web Technologies

Community Organizer and Online Teacher

https://guillermorodas.com

@glrodasz

You can Google me as well.

AGENDA

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

Static Testing, a software testing technique in which the software is tested without executing the code.

Typically used to find and eliminate errors or ambiguities in documents such as requirements, design, test cases, etc.

Code review

The code written by developers is analyzed (usually by tools) for structural defects that may lead to defects.

Static analysis

ESLint

Unit Testing

IN & OUT

(A little bit of black-box testing)

💪 Enhance your learning

What is the difference between black-box and white-box testing?

Given "A"

 

Then  "C"

When "B"

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

MOCKING

(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

🙈

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'

🐒

Dependency Injection

💉

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.

💪 Enhance your learning

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      '){}
}

Unit Testing: Structural

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)
    }
}

📸 Snapshot Testing

describe('when    '){
    it('should render'){
     expect(Foo(    )).toMatchSnapshot()
    }
}
     expect(Foo(    )).toMatchSnapshot()

Unit Testing: Interaction

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 Testing

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'

USING E2E TOOLS

(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

Integration Testing:

Visual Testing

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

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.

Why not use Selenium?

Write tests. Not too many. Mostly integration

Questions??

Introduciton to Testing

By Guillermo Rodas

Introduciton to Testing

An introduction guide about how to test in JavaScript

  • 1,175