Testing


Testing

Updated Jun 2nd, 2022

Notes from fireship JEST video here or the 100 seconds of testing here.

Another good video here from LeeRob. React testing library something to look into.

Red > Green > Refactor. This means you write your failing test first, then you refactor, then you get is passing, and then you refactor. Helpful with very clear requirements.

“I do test-driven development.” Process where you describe the behavior of your code before you go and implement it. Trust the science, it works. A very valuable skill to have.

Can be fun, teach about your code in unexpected ways.

Walks fine line of being valuable versus a complete waste of time.

Jest is a JavaScript testing framework designed to ensure correctness of any JavaScript codebase. They run your automated tests either in the background or on a continuous integration server before you deploy. (Karma is another “test-runner” that is an alternative to Jest)

Testing is a way to level up your coding skills and can be fun (-fireship.io test driven development)

Manual testing is not really scalable. So there’s automated testing.

Write more code now to keep tabs on your critical code

Files end in “.spec” or “.test” extensions.

Different Testing Strategies

Unit testing – Lowest level of testing, goal is to validate behavior of units of code, (functions, methods, etc.). Jest.

Integration testing – Testing multiple units of code together. Jest.

End to End – Runs your application in a simulated environment and attempts to emulate actual user behavior. There is a program named “Cypress.io” that has a browser-based test-runner). Most valuable for Jeff form Fireship.

Note: These three testing strategies above are the bulk of it.

Acceptance testing – Makes sure the software meets all of the clients needs are met.

System testing – Make sure everything works on an actual server or hardware.

Smoke tests – Like “Sanity,” have thousands of tests to run, runs a few of the most important tests to make sure the app doesn’t “catch fire.”

Everything to this points describes functional testing but also have tests for things like performance, usability, and security (terms like stress-testing).

May see “jasmine” syntax out there. Jasmine is a behavior-driven development framework for testing JavaScript code. It does not depend on any other JavaScript frameworks. It does not require a DOM. And it has a clean, obvious syntax so that you can easily write tests.

Hands Dirty Example: Implement a Stack without using a JS Array

Source code on course repo, gets a simple project going with:

npm init @vitejs/app

And then runs:

npm install jest
// will be looking for "something.test.js" files

Add a testing file “test/stack.test.js” and add a “test” script in the “package.json” file.

"test":"jest --watchAll --verbose"
// run "npm run test" to get first failing test
npm install @types/jest

Now create a “jsconfig.json” file that has a “typeAcquisition” property.

"typeAcquisition": {
  "include": [
    "jest"
  ]
}

Note: this step is optional to get better VS Code autocompletion. The presence of jsconfig. json file in a directory indicates that the directory is the root of a JavaScript Project. The jsconfig. json file specifies the root files and the options for the features provided by the JavaScript language service.

Another pro-tip is that we may want to install the “Wallaby.js” plugin that is a paid VS Code extension with a free tier. With tell you whether or not your tests are passing directly in the editor without having to look in the terminal.

describe("My Stack", () => {
  it.todo('is created empty')
  it.todo('can push to the top')
  it.todo('can pop off')
})

The “.todo” method is to hold off on the test while you’re figuring things out.

describe("My Stack", () => {
  it('is created empty')
    const stack = new Stack 
    expect(stack.top).toBe(-1) // matcher
  it.todo('can push to the top')
  it.todo('can pop off')
})

This will fail and so we can start to solve the errors by defining a class above the existing code.

class Stack {
  constructor() {
    this.top = -1
    this.items = {}
  }
}
describe("My Stack", () => {
  it('is created empty')
    const stack = new Stack 
    expect(stack.top).toBe(-1) // matcher
  it.todo('can push to the top')
  it.todo('can pop off')
})

Note: you can add multiple “expectations” to a single test.

class Stack {
  constructor() {
    this.top = -1
    this.items = {}
  }
  get peek() {
    return this.items[this.top]
  }
  push(value) {
    this.top += 1
    this.items[this.top] = value
  }
}
describe("My Stack", () => {
  let stack;
  before(() => {
    stack = new Stack()
  })
  it('is created empty')
    const stack = new Stack 
    expect(stack.top).toBe(-1) // matcher
    expect(stack.items).toEqual({}) // better choice for the matcher
  it.todo('can push to the top', ()=> {
    stack.push()
    expect(stack.top).toBe(0)
    expect(stack.peek).toBe("avocadoemoji")
  })
  
  it.todo('can pop off') // can we do this one on our own
})

It’s not always your main application code that is the problem, it may be the testing code and we don’t write tests for our tests.

Code duplication can get bad inside of a test suite.

Write the test, fail the test, write code to pass the test. Satisfying to turn test from red to green.

Going to also want to run a “Code coverage report” which tells you the percentage of code covered by your test suite, but mostly just a false sense of security.

// in the "package.json" file
"test":"jest --watchAll --verbose --coverage"

Detailed Look at End to End Testing

More fun and interesting, E2E test is very long and complex and takes a while to run because it simulates actual user behaviors. favorite way to run e2e test is to use “cypress” that will download and run a browser to run the tests.

Can use a mock database and mock validation to help be more realistic.

Define a test suite and then write some tests.

The “cypress” tool makes it easy to code these tests. Has j-query-like syntax. Common methods look like (“.visit, .type, .should, .get)

From an Academind Video

Great watch. Did Unit and integration tests with Jest and brought in puppeteer to do E2E testing.

List of Testing Methods and Properties

.test() // jest

.expect() // jest

.toBe() // jest

.launch() // pup

headless: false,
slowMo: 80,
args: ['--window-size=1920,1080']

.newPage() //pup

.goto() // pup

.$eval() // pup

.type() // pup

.click() // pup