- [Instructor] Determining if actual output
matches the expected is a requirement for testing
if a system is working correctly.
Assertion libraries are the solution, but what are they?
As you may recall,
an assertion validates the correctness of a unit of code.
Assertions declare that a given predicate
is going to be Boolean true.
For example, here's an assertion
that 'dog' is strictly equal to 'cat.'
In this case, the assertion will throw an error
because the string literals do not match.
All right.
So what's an assertion library?
An assertion library is a collection of assertions.
Typically many more than what's in Node.js's assert module.
They support comparisons
of many different types of language structures
like objects or rays, Booleans, numbers and more.
Like a framework,
assertion libraries provide an API,
or in some cases multiple APIs
for developers to create predicates.
The APIs provide interfaces and styles
like test driven development or behavior driven development.
Here's a few of the types of assertions
that are included in a library.
I check to see if something is defined
or more explicitly not undefined.
The any assertion checks to see if it was created
by a given constructor, such as number.
In a similar way,
you can determine if an object is to be an instance
of a particular constructor.
Sometimes it's helpful to check that an object
has a given property with ToHaveProperty.
If you're testing a promise,
Resolves declares an object is a promise
and will resolve to a specific value.
Some assertion APIs provide support for language chaining.
A chaining assertion is a special kind of assertion.
In itself,
it checks nothing and won't throw any errors.
However, it will pass a value between assertions.
This goes back to supporting natural language
when describing assertions,
such as with behavior-driven development.
Change assertions have multiple aliases,
all of which do the same thing.
Terms like "be," "an," "of," "and," and so forth
help build assertions that sound like a sentence.
Let's revisit the reservation creation example
from earlier in a framework that supports chaining.
Same as before,
it should create a reservation with an email.
Given the email 'username@example.com,'
when a reservation is created,
this is when the chaining happens.
Then the reservation should have the property email.
The word "have" is a chain
along with "and" to compare the email property
with a given.
Chaining can improve readability
and leads to a more natural sounding description,
but isn't available in every assertion API.
There are a number of assertion libraries available.
The first is Assert, which is Node.js's native module.
Another popular library is Chai,
available from chaijs.com.
Should.js from shouldjs.github.io is also popular.
Some test frameworks have assertion libraries built-in
including Jasmine, which has matchers
and Jest which has expect methods.
I'm going to compare assertion libraries
in much greater detail with code examples in chapter three.
Throughout this chapter,
we've learned about the fundamental terms and concepts
in testing and code quality.
We started with a definition of code quality
and why it matters.
Then we explored coding conventions and coding standards
and how they can be used to improve code quality.
We discussed how to create and enforce a coding standard,
including how to collaborate with a team to write one.
We introduced unit, integration, functional
and system testing and compared to how they interact
with different parts of the application.
We looked at how testing frameworks
can automate testing.
Then compared different approaches
to writing test specifications
using processes like behavior-driven development.
Finally, we found more ways
to check correctness using assertion libraries.
With this foundation,
we're ready to add a coding standard
to our existing application
and start linting for code quality.
But first, take a moment to practice your skills
with a brief challenge.