JavaScript Testing
Who Am I
- My name is Jedediah Smith
- I love JavaScript, working with data, and organizing chaos.
- I enjoy teaching, training, mentoring, and otherwise helping others with their code.
-
I work for CurbNTurf where we connect land owners and RVers
- A Book I Am Writing: JedJS.com
- Twitter: @jedsmith13
- LinkedIn: https://www.linkedin.com/in/jedediahsmith
What are Tests
According to Wikipedia
A test is an assessment intended to measure a test-taker's knowledge, skill, aptitude, physical fitness, or classification in many other topics. A test may be administered verbally, on paper, on a computer, or in a predetermined area that requires a test taker to demonstrate or perform a set of skills.
https://en.wikipedia.org/wiki/Test_(assessment)
What are Tests
How about the Dictionary (or Google's equivalent)
1. a procedure intended to establish the quality, performance, or reliability of something, especially before it is taken into widespread use.
https://www.google.com/search?q=what+are+tests
What are Tests
The reason(s) I would write a test
- Confidence
- Confidence
- Confidence
https://www.google.com/search?q=what+are+tests
Types of Tests
No Open-book Tests here
Types of Tests
- In Production
- In Beta
- Manual
- End To End (e2e)
- Integration
- Unit
- Static
- Regression, functional, system, sanity, smoke
interface, etc... - Security, usability, load, etc...
Types of Tests
- In Production (possibly your business or job)
- In Beta
- Manual
- End To End (e2e)
- Integration
- Unit
- Static
Sorted By Cost Per Test
High
Low
Advantages/Disadvantages
Advantages
- No developer time
- Maximum flexibility for developer and project
- Tested by exact customer base
In Production
Disadvantages
- Angry former customers
- Late nights and weekends spent fixing bugs
Advantages/Disadvantages
In Beta
Advantages
- No developer time
- Fairly good sample of customer base
- More sympathetic users
Disadvantages
- Slow to deploy
- Often requires paying customers (either in free usage or other)
Advantages/Disadvantages
Manual
Advantages
- Can have very high confidence
- Less developer training
Disadvantages
- Slow
- Boring
- Easy to skip steps after repeated attempts
- "It worked last time I tried it"
Advantages/Disadvantages
e2e
Advantages
- High confidence
- Tested similarly to how a user will use the site
- Don't need holes in reality
Disadvantages
- Slow
- Can be complex to create
- Can break on UI rework without code changes
- Can be expensive if paying for 3rd-party APIs
Advantages/Disadvantages
Integration
Advantages
- Simpler to write
- Good confidence in the application
- Faster then e2e
Disadvantages
- Slower then Unit tests
- Can be more complex then Unit tests
- Can be expensive if paying for 3rd-party APIs
- May need some mocking
Advantages/Disadvantages
Unit
Advantages
- Quick
- Can be simple to write
- High confidence in functions/units
Disadvantages
- Mocks add complexity
- Doesn't test interactions between units
Advantages/Disadvantages
Static Tests
Advantages
- Lightning fast
- Basically free to write
Disadvantages
- Only tests static code and structure
No Tests
Every Test
Where should we be?
Unfortunately, the answer is, that it depends.
Points to Consider
- User base
- Speed to delivery
- Life expectancy
- Rate features will be added after release
- # of developer
- Skill of developers
- Complexity of app
- Deployment processes (CI vs waterfall)
- # of 3rd party integrations
- Stability of code and APIs
No Tests
Every Test
Widely Used Library
Libraries that are depended on should be thoroughly tested.
If you use an open source library that isn't tested as well as you would like, consider adding some to a PR for everyone's benefit.
No Tests
Every Test
Autonomous Car
Anything involving the safety of lives should be tested extensively from many different approaches.
No Tests
Every Test
Banking App
Anything involving finances should be thoroughly tested and not just for security vulnerabilities. People tend to get upset when their money disappears.
No Tests
Every Test
Large Enterprise Level App
The larger and the more complex the app the more you benefit from automated tests.
No Tests
Every Test
I am Learning React
If you are just creating a site to learn a new tech don't worry about tests, unless that is part of learning the new tech.
No Tests
Every Test
My App
If your app wasn't listed then it is probably in the middle somewhere.
?
No Tests
Every Test
CurbNTurf
We started with very few tests (read only what was pre-built in the scaffolding) until we had a somewhat stable API and we are now increasing our code coverage as we add or refactor features.
Where We Started
- Testing API endpoints
- A few e2e paths
- Unit test helper functions
- New features
- More tests (as I learn how to write them)
Testing API Endpoints
Tool: Cypress
Setup: Using a Docker instance of the database with pre-populated fields and a separate instance of the server. Writing the tests was pretty simple with Cypress. The setup did take a bit of work to get the data database and to keep it up to date. It is also kind of slow already.
import * as usersJson from '../../fixtures/users.json';
const API_URL = Cypress.env('API_URL');
const users = usersJson as any;
describe('User API: Fetch', () => {
it('if same user returns JSON, has hasCC field', () => {
(cy as any)
.loginByRequest(users.generic.email, users.generic.password)
.then((authToken: string) => {
cy.request({
url: `${API_URL}/user/${users.generic.id}`,
method: 'GET',
headers: { Authorization: authToken },
}).then(response => {
expect(response.body).to.be.an('object');
expect(response.body.email).to.not.be.undefined;
});
});
});
it('if not logged in returns JSON, does not have email', () => {
cy.request({
url: `${API_URL}/user/${users.generic.id}`,
method: 'GET',
}).then(response => {
expect(response.headers['content-type']).to.include('application/json');
expect(response.body).to.be.an('object');
expect(response.body.email).to.be.undefined;
});
});
});
Example:
Tool: Cypress
Setup: Using a Docker instance of the database with pre-populated fields and a separate instance of the server. Writing the tests was much simpler then expected with Cypress. Used the same database setup as used for the integration tests.
A few e2e paths
context('Handle Profile', () => {
beforeEach(() => {
(cy as any).loginByForm(users.generic.email, users.generic.password);
cy.get('#profile-heading').click();
});
it('can update the user profile information', () => {
cy.get('input[formcontrolname=firstName]').type(users.generic.firstName);
cy.get('input[formcontrolname=lastName]').type(users.generic.lastName);
cy.get('#user-profile-save-button')
.click()
.then(() => {
// we should have visible response now
cy.get('.toast-title')
.should('be.visible')
.and('contain', 'User Updated');
});
});
});
Example:
Other Advantages of Tests
- Can be used to identify difficult code
- Can be used to guide the development
- Can encourage better coding practices
Many of the developers I read, listened to, or watched mentioned these as primary reasons why everyone has to write tests. I see these as secondary benefits that can be had other ways.
Some False Statements about Tests
- Written tests lead to bug-free code
- 100% code coverage leads to bug-free code
- If we write tests we don't have to do manual testing
Your tests only cover bugs you already identified.
Some Other Items
- e2e and integration are better for refactoring
- Unit test are quick to run so they are better for sections of code needing thorough testing
- Cypress allows running smaller groups of tests easily
Your tests only cover potential bugs you already identified.
JavaScript Testing
By Jedediah Smith
JavaScript Testing
The problem of deciding how much of which test to use.
- 652