In many of your previous coding tasks, you had to verify that your code
worked before moving to the next step. This often required you to add
console.log
statements to your code to check the value stored in a variable
or returned from a function. This approach finds and fixes syntax, reference,
or logic errors AFTER you write your code.
In this chapter, you learned how to use unit testing to solve coding errors. Even better, you learned how to PREVENT mistakes by writing test cases before completing the code. The exercises below offer practice with using tests to find bugs, and the studio asks you to implement TDD.
Let's begin with the following, simple code:
1function checkFive(num){
2 let result = '';
3 if (num < 5){
4 result = num + " is less than 5.";
5 } else if (num === 5){
6 result = num + " is equal to 5.";
7 } else {
8 result = num + " is greater than 5.";
9 }
10
11 return result;
12}
The function checks to see if a number is greater than, less than, or equal to 5. We do not really need a function to do this, but it provides good practice for writing test cases.
Note that the repl.it contains three files:
checkFive.js
, which holds the code for the function,checkFive.spec.js
, which will hold the testing code,index.js
which holds special code to make Jasmine work.Warning
Do NOT change the code in index.js
. Messing with this file will disrupt
the automatic testing.
We need to add a few lines to checkFive.js
and checkFive.spec.js
to
get them to talk to each other.
checkFive.spec.js
needs to access checkFive.js
. Add a require
statement
to accomplish this (review Unit Testing in Action if
needed).
Make the checkFive
function available to the spec file, by using
module.exports
(review Unit Testing in Action if
needed).
Set up your first test for the checkFive
function. In the
checkFive.spec.js
file, add a describe
function with one it
clause:
1const checkFive = require('../checkFive.js');
2
3describe("checkFive", function(){
4
5 it("Descriptive feedback...", function(){
6 //code here...
7 });
8
9});
Now write a test to see if checkFive
produces the correct output when
passed a number less than 5.
First, replace Descriptive feedback...
with a DETAILED message. This
is the text that the user will see if the test fails. Do NOT skimp on
this. Refer back to the Specifications and Expectations
section to review best practices.
Define the variable output
, and initialize it by passing a value of
2
to checkFive
.
1const checkFive = require('../checkFive.js');
2
3describe("checkFive", function(){
4
5 it("Descriptive feedback...", function(){
6 let output = checkFive(2);
7 });
8
9});
Now use the expect
function to check the result:
1const checkFive = require('../checkFive.js');
2
3describe("checkFive", function(){
4
5 it("Descriptive feedback...", function(){
6 let output = checkFive(2);
7 expect(output).toEqual("2 is less than 5.");
8 });
9
10});
Run the test script and examine the results. The test should pass and produce output similar to:
Started
.
1 spec, 0 failures
Finished in 0.006 seconds
Now change line 3 in checkFive.js
to if (num > 5)
and rerun
the test. The output should look similar to :
Started
F
Failures:
1) checkFive should return 'num' is less than 5 when passed a number smaller than 5.
Message:
Expected Input A to equal Input B:
Change line 3 back.
Note
We do NOT need to check every possible value that is less than 5. Testing a single example is sufficient to check that part of the function.
Add two more it
clauses inside describe
---one to test what happens
when checkFive
is passed a value greater than 5, and the other to test
when the value equals 5.
Time for Rock, Paper, Scissors! The function below takes the choices
('rock'
, 'paper'
, or 'scissors'
) of two players as its parameters.
It then decides which player won the match and returns a string.
1function whoWon(player1,player2){
2
3 if (player1 === player2){
4 return 'TIE!';
5 }
6
7 if (player1 === 'rock' && player2 === 'paper'){
8 return 'Player 2 wins!';
9 }
10
11 if (player1 === 'paper' && player2 === 'scissors'){
12 return 'Player 2 wins!';
13 }
14
15 if (player1 === 'scissors' && player2 === 'rock '){
16 return 'Player 2 wins!';
17 }
18
19 return 'Player 1 wins!';
20}
Set up the RPS.js
and RPS.spec.js
files to talk to each other. If
you need to review how to do this, re-read the
previous exercise, or check
Hello Jasmine.
Write a test in RPS.spec.js
to check if whoWon
behaves correctly
when the players tie (both choose the same option). Click "Run" and examine
the output. SPOILER ALERT: The code for checking ties is correct in
whoWon
, so the test should pass. If it does not, modify your it
statement.
Write tests (one at a time) for each of the remaining cases. Run the tests
after each addition, and modify the code as needed. There is one mistake in
whoWon
. You might spot it on your own, but try to use automated
testing to identify and fix it.
What if something OTHER than 'rock'
, 'paper'
, or 'scissors'
is
passed into the whoWon
function? Modify the code to deal with the
possibility.
Don't forget to add another it
clause in RPS.spec.js
to test for this
case.