Skip to content

Instantly share code, notes, and snippets.

@zcaceres
Created March 14, 2017 15:50
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save zcaceres/b994f03db1ab70b15b0e29ff18555107 to your computer and use it in GitHub Desktop.
Save zcaceres/b994f03db1ab70b15b0e29ff18555107 to your computer and use it in GitHub Desktop.
testing wikistack notes

Testing (Wikistack)

1. Don't become a Horror Story

2. How to Start


A Brief History of Testing:

People (a script) ==> Macros (automated scripts) ==> Unit Testing (starting 1990's)

1. Don't become a horror story

Rushing, emergency pushing, spray and pray, and other ill-advised approaches to coding all can become a horror story!

Avoid a horror story with...

Unit Testing

Benefits:

  • Ensure code is working
  • Documents what code is supposed to do
  • Tests offer precision in behavior
  • Don't break what's already working (avoiding regressions)
  • Forces you to think about how your code will function in advance
  • For your own peace of mind!

2. How to Start

A testing library suite really just has:

  • Labels (describe)
  • Functions (it)
  • Assertions (expect)

Assertions are Remarkably Simple

Assertions like expect is really just a thing that throws errors! It's remarkably simple.

We assert a state or value. If an error is thrown, we throw it and show it to the user. If not, then we say 'It was a pass'.

TDD: Test Driven Development

Writing tests before you write your code. It grounds you in your goals: because you're writing your tests first. You always end up with automated tests because you're writing them from the start!

Some studies suggest that TDD helps modularity. You often have to refactor as you move through tests. This creates a process of continuous refinement, where you end up with simpler, more modular code.

TDD also has disadvantages:

  • It's HARD!
  • Requirements may change (a lot), quickly making our tests obsolete.
  • Harder to write code in an exploratory manner

TDD Flow

    1. Add a test

    2. Run the Tests

    3. Make a little change

    4. Run the Tests

    5. Repeat from Step 1

Frameworks have a lot of commonalities. If you learn Mocha or Chai or Jasmine, you can easily pick up another. It's more important to understand what makes a good test.

Automated Testing ≠ TDD

You can like AT without doing TDD!

Principles of Good Tests

Write your tests to be as stupid as possible.

Remember, we want our tests to be as easy to reason about as possible! We don't want to have to test our tests! Keep it straightforward.

  • Tests must be isolated.
  • Test as small of a thing as you can at once.
  • Do not make tests dependent on each other
  • Reduce moving pieces
  • Reduce state – for example, don't make your test depend on the state or outcome of a previous test.

Stubs/Fakes: Making a function that varies and making it predictable.

Designing:

  • High level behavior: such as what should my return value be?
  • Make it fail. Always know how your test can fail and see it fail.
  • Behavior: you may need to use edge cases to find good ways to test your code. Or, you may need to use a stub/fake.

If you don't need DB persistence, use .build() in Sequelize rather than .create().

Before/BeforeEach/AfterEach

These are examples of methods that allow us to better isolate tests through set up and tear down.

Methods like these allow us to create a isolate environment for each test.

Before is run before all of our tests. beforeEach, is run before all of our its within a describe block.

When Do I Stop Writing Tests and Start Coding?

Usually, you keep alternating:

  • Write one test.
  • Write code to pass it.

Nesting describes and its

it tells us that there will be an expectation. its will be run sequentially.

describe is a useful organizational tool for bundling your tests together. Our test results will take our describes and then our it to create a path/message to the test block.

Usually the describe hierarchy matches the hierarchy of the code.

Two Ways to Handke: Async Tests

With done() When we are testing something async, we must pass in done to our it block. Then we invoke done() after our expect.

done is always passed into your it, so you can name it anything you want!

If we have an error, we must catch() it, as with Promises, and then call done() after our error.

With a promise We can actually put our Mocha/Chai promise into a promise that we create in our tests!

Then, using a promise chain, we can run our test only after the Promise is resolved.

After our promises are done we return them. Mocha then evaluates that promise for pass/fail.


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment