Unit testing with Jasmine / getting started with TDD
Tags: tdd, unittest, jasmine
Published: 2021-12-16 14:59:45

# TDD(Test-Driven Development)
Test-Driven Development (TDD) is a **software development process** relying on software requirements being converted to test cases before software is fully developed, and <u>tracking all software development by repeatedly testing the software against all test cases</u>. This is as opposed to software being developed first and test cases created later. (from [wikipedia](https://en.wikipedia.org/wiki/Test-driven_development))

# Unit Test
Unit test is a way of testing a unit. Unit means the **_smallest piece of code that can be logically isolated in a system_**. In most programming languages, that can be function / method or property.

# TDD Approach - Red, Green, Refactor
Test-driven development (TDD) is an approach to software development **where you write tests first**, <u>then use those tests to drive the design and development</u> of your software application.
- Red: think about what you want to develop, This is where you fail from your tests.
The purpose of this phase is to write tests that informs the implementation of a feature. **The test will only pass when the its expectations are met.**
- Green: think about how to make your tests pass.
This is where you implement code to make your test pass. The goal is **to find a solution**, without worrying about optimizing your implementation.
- Refactor: think about how to improve your existing implementation.
In the refactor phase, you are still "in the green." You can begin thinking about how to **implement your code better or more efficiently**. If you want to think about refactoring your implementation code, you can think about <u>how to accomplish the same output with more descriptive or faster code.</u>

Article about [Red, Green, Refactor](https://www.codecademy.com/article/tdd-red-green-refactor)

# Getting started with Jasmine
Jasmine: https://jasmine.github.io/
These are files that's downloaded from Jasmine.
![jasmine](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zifso52j0ext8he1ddze.png)

And these are filed that I created to start with.
![setting with jasmine](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eehr51rtyji02xgla8i4.png)
Those files that include "spec" in their name are for test. Other two are files that will be deployed.

from the file I downloaded, it had a file name SpecRunner.html
```html
 <link rel="shortcut icon" type="image/png" href="lib/jasmine-3.10.1/jasmine_favicon.png">
 <link rel="stylesheet" href="lib/jasmine-3.10.1/jasmine.css">

 <script src="lib/jasmine-3.10.1/jasmine.js"></script>
 <script src="lib/jasmine-3.10.1/jasmine-html.js"></script>
 <script src="lib/jasmine-3.10.1/boot0.js"></script>
 <!-- optional: include a file here that configures the Jasmine env -->
 <script src="lib/jasmine-3.10.1/boot1.js"></script>
```
I copied and pasted these lines at the bottom of **`head`** tag in my TDD.spec.html file and changed the route correctly according to mine.

## TDD.spec.html
```html
<!DOCTYPE html>
<html lang="ko">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title></title>
    <link rel="shortcut icon" type="image/png" href="jasmine/lib/jasmine-3.10.1/jasmine_favicon.png">
    <link rel="stylesheet" href="jasmine/lib/jasmine-3.10.1/jasmine.css">

    <script src="jasmine/lib/jasmine-3.10.1/jasmine.js"></script>
    <script src="jasmine/lib/jasmine-3.10.1/jasmine-html.js"></script>
    <script src="jasmine/lib/jasmine-3.10.1/boot0.js"></script>
    <!-- optional: include a file here that configures the Jasmine env -->
    <script src="jasmine/lib/jasmine-3.10.1/boot1.js"></script>
</head>


<body>
    <!-- This html file is for the test (To check test result) You can check the test result when you open this in browser -->
    <!-- This file below is for the test -->
    <script src="tddTest.js"></script> 
    <!-- This file below is for unit test -->
    <script src="tddTest.spec.js"></script>
</body>

</html>
```
**Note.** You must include "**`spec`**" in the name for test file so that Jasmine will recognise it as a test file.


# tddTest.spec.js
```js
// Test units will be written here. function it() will be used a lot.
// This file is spec file of tddTest.js

describe("this is jasmine test", () => {
  // this is test unit
  it("function for addition", () => {
    let num = 10;

    // it, expect, toBe are functions used in jasmine. (Because of library, you can simply type the name of these function and use!)

    // expect: This will pass the result of function
    // toBe: it's a function checking if my expectation meats the result 
    // plusOne inside expect()is a function/code to test 
    expect(plusOne(num)).toBe(num + 1);
  });
});

```

This is Red stage from TDD Approach
![red stage tdd](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s5g0qoa8ts0caq1slpwz.png)
The error got caused is because I have this **`expect(plusOne(num)).toBe(num + 1);`** code in tddTest.spec.js but function plusOne was never defined. If you open TDD.spec.html using live server,
You can see what's exactly wrong on the test page using Jasmine.

## tddTest.js
```js
function plusOne(num) {
  return num + 1;
}
```
So I wrote a function plusOne in tddTest.js
Now go to TDD.spec.html using live server

![green stage tdd](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ng7fancjt91uaszslszg.png)
and this green page appears.
It's written just to see how Jasmine work so it's very short code but this is how you do the testing. You will go back and forth from red to green and green to red every time you add a new line of code to test and to write a code to make it pass.

# TDD.html
```html
<!DOCTYPE html>
<html lang="ko">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title></title>
    <link rel="shortcut icon" type="image/png" href="jasmine/lib/jasmine-3.10.1/jasmine_favicon.png">
    <link rel="stylesheet" href="jasmine/lib/jasmine-3.10.1/jasmine.css">

    <script src="jasmine/lib/jasmine-3.10.1/jasmine.js"></script>
    <script src="jasmine/lib/jasmine-3.10.1/jasmine-html.js"></script>
    <script src="jasmine/lib/jasmine-3.10.1/boot0.js"></script>
    <!-- optional: include a file here that configures the Jasmine env -->
    <script src="jasmine/lib/jasmine-3.10.1/boot1.js"></script>
</head>

<body>
    <!-- TDD.html, tddTest.js are only file will be deployed -->
    <script src="tddTest.js"></script>  
   <!-- spec files are for testing. These won't be pushed but in some teams/companies they will have their main branch and dev branch. Usually those tests file would got o dev branch but will NEVER go to the main -->
    <!-- <script src="tddTest.spec.js"></script> -->
</body>

</html>
```
I created four files for unit test here.
- TDD.spec.html
- tddTest.spec.js
- tddTest.js
- TDD.html

But like what I've mentioned above, spec files are made to do the test and they will not be pushed.
*These are way to short to refactor so I will probably write another example to explain the refactoring stage.

# Things to consider 
- Writing test code takes much more time of course, so if the project needs to be finished urgently, it might not be the best case to use.
- TDD is a good way to develop. However, test code is written by human as well and we can still make mistakes. There will be things that we didn't consider enough so writing test code doesn't mean that the code written are perfect. Doing TDD is to have structured code that's easy to maintain and refactor.