The 7 Principles of Testing

This section will cover the following:

Why Test?

The purpose of testing software is to remove

  1. Errors
  2. Defects
  3. Failures

Errors caused by code that is incorrectly implemented. Defects caused by code that works, but does not work in the way it is intended too. Failures cause your software to stop working all together. Testing tries to ensure these three things have been removed from your software.

The 7 Principles of Software Testing

testing systems

In the diagram above you can see the International Software Testing Qualifications Board’s 7 principles of testing.

To exhaustively test is not practical or possible. For example 15 fields in a form that can each take one of 5 possible values would required 30,517,578,125 unit tests to prove each combination. Please don’t do that. What we need are testing strategies.

👩‍💻🧑‍💻

In pairs discuss the following scenario. I have a file in folder A and want to move it to folder B. List all the things that could go wrong and prevent this file moving successfully?

4 Different types of testing

  1. Unit
  2. Integration
  3. End-to-end (System)
  4. Acceptance

Unit Testing

Unit Tests isolate a section of code and verify its correctness. A unit may be an individual function, method, procedure, module, or object. Unit tests are static tests (see below).

Integration Testing

Integration tests determine if independently developed units of software work correctly when they are connected to each other. These tests often assert behaviours, and can be static or dynamic. For example calling this endpoint;

/users/x023/photos

should return a JSON string with an array of urls. This is testing that the server correctly interacts with the database and returns the correct values.

System Testing or End-to-end Testing

The whole system is run. This is a dynamic test. Examples of system testing are end-to-end tests; automated, codified interactions (see cypress.io) with assertions of state or outputs. Other examples of system testing include;

Acceptance Testing

The purpose of this test is to evaluate the system’s compliance with the business requirements and assess whether it is acceptable for delivery. You built a perfect bridge, but have you met the business requirements?

bridge built in wrong place

6 Different techniques of testing

  1. Static/Dynamic
  2. White Box/Black Box
  3. Functional/Non-functional
StaticDynamic
static vanmoving van
Static tests do not require your app to be running. You can test things on a static vehicle; for example do the lights work? can you move the seats?Dynamic tests require your app to be running. To really test the breaks of a vehicle, you need to drive it.
Black BoxWhite Box
black box testingwhite box testing
Black box testing asks WHAT the system does. WHAT inputs produce WHAT outputs.White box testing tests HOW things work? HOW does your branching logic work? Does the structure of the code deal with all the possible states?
FunctionalNon-functional
  • Do the breaks work?
  • Does the route load on the map ok?
  • Does auto pilot initiate ok?
  • Does it feel safe?
  • It is boring?
  • Is it easy to stop the auto pilot?

Functional testing is binary. Think PASS/FAIL. On a form functional input might be a checkbox.

Non-functional testing is NOT binary, it requires more explanation. Think FEELINGS? On a form non-functional input might be a free text field inviting your thoughts.

Equivalence classes and Use Cases

We looked at equivalence classes in Module 1 Unit 5 they should also be considered as we design our testing strategies.

In your all your projects, but in particular your final workplace project you need to consider how are you going to test your code. We've looked at lots of different aspects of testing, use this to help you develop your testing strategies.

Assignment

  1. Download this codebase
  2. Can you implement the testing pyramid by adding at least one of each type of test
Unit Teststips
Testing pyramid: unit tests make up the base of the pyramid; integration tests in the middle; end-to-end tests at the top
tip get your unit tests to run separately from E2E cypress tests. In the root level of your package.json add
"jest": {
  "testPathIgnorePatterns": ["spec"]
}
Now name your unit test files filename.test.js and your cypress test files filename.spec.js. Add a npm script npm run test:unit that runs only the unit tests in the unit folder with a script like PORT=3001 jest --testPathPattern=/tests/unit.
Integration Teststips
For integration tests you can use a library like axios to make http requests to the running test instance of your server.I have been using a node module called start-server-and-test to start a test instance of the app, then wait for http://localhost:3001 to be ready before running the tests, the module will then tearing everything down for you. You'll appreciate a script that exits cleanly when we come to automate these tests later. Read the instructions about how to use start-server-and-test you will need a few npm scripts to use it.
{
    "scripts": {
        "test:serve": "NODE_ENV=test PORT=3001 node server.js",
        "test:integration_tests": "NODE_ENV=test PORT=3001 jest --testPathPattern=/tests/integration",
        "test:integration": "start-server-and-test test:serve http://localhost:3001 test:integration_tests",
    }
}
End-2-end Teststips
This project has Cypress set up with a sample test, can you add to these system tests?Use start-server-and-test for your end to end tests as well