Lab 8 and Testing Apps
Tags: opensource
Published: 2020-11-28 01:59:26

Testing: the backbone of any project. A project without the ability to test its code will inevitably bloat in a way that breaks EVERYTHING.

I don't think I need to actually explain the philosophy, but I will anyway. Basically, you need tests to make sure no one breaks the project as they're working. When you have a project of any reasonable size, you can expect that someone will fix a bug or add a feature that causes a different part of your project to not work. So we need to automate tests that will check to make sure we haven't done that before we go to add the feature or bug fix.

So to that end, let's write some tests!

###Jest test for printing a working url
```
test('print good url', async () => {
        const expected = chalk.green('[200] GOOD http://www.google.ca')
        const result = isValid.displayStatusCode(200, 'http://www.google.ca')

        expect(result).toEqual(expected)
    })
```

##The Framework
So we decided to use Jest! It's a great framework for testing Javascript projects. To do this, we simply use ``npm install --save-dev jest`` and go off! I created a test folder and put my testing files in there.

![lab8_1](https://dev-to-uploads.s3.amazonaws.com/i/imffgy3qhbwsnmhftq5w.png)

Inside the testing file, we define the files we're using and start writing tests! 

![lab8_2](https://dev-to-uploads.s3.amazonaws.com/i/xrsmbxbaimjlhp50srfo.png)

##The Tests

The first test I wrote was the most difficult. Actually, that applies to every category of test. Because we're testing the same function - just different lines through - we need to write one good test, and we can kind of reuse it for our other lines.

![lab8_3](https://dev-to-uploads.s3.amazonaws.com/i/gulgx8oieqph97z89342.png)

However, there wasn't anything particular that stood out to me as supremely difficult.

No particular bugs either, though I did learn about how my code works a bit more and had to check for undefined in some tests (which is, forgive the rhyme, rather unrefined a solution). I also realized I had to modulate my code a bit and separate some functions into their own files. This will be extremely beneficial for the future in general.

##The Mock Tests

One of the most important parts of my app is checking for a response from a website. We want to know if the website will return 200 good or 404 broken, you know? However, you can't really check a real site in tests because what if it goes down? That's what mocking is for.

###A test function that mocks a link to always output 405 status code
```
const host = 'https://www.youtube.com'
const path = '/'

test('get 405 response for unknown url', async () => {
        nock(host).head(path).reply(405)
        const url = `${host}${path}`
        const expected = chalk.gray(`[405] UNKNOWN ${url}`)
        const result = await isValid.isValid(url)

        expect(result).toEqual(expected)
    })
```

We use [nock](https://github.com/nock/nock) here to easily mock an address and send it to our function.

Easy!

##Code Coverage

Code coverage is a description of exactly how much of your code is being tested by your tests. For example, if I'm writing 1 test that goes through 1 line of a function while there are 3 possible lines, my code coverage is 1/3 (realistically more but for the purposes of explanation let's say 1/3). So I need to write some more tests to expand that.

Also, there are tools one can use to inspect how much code is being covered by our tests.

![lab8_4](https://dev-to-uploads.s3.amazonaws.com/i/d275hhr30ted1o1actie.png)

Jest has such a feature! pictured above, all you have to do is specify --coverage when you run jest.

###package.json excerpt
```
"scripts": {
    "test": "jest --detectOpenHandles --coverage",
    "prettier": "npx prettier --write .",
    "lint": "npx eslint ."
  },
```

I think it would be good to set coverage as a separate option, but also I think it should run for any user who is submitting tests because who wouldn't want as much coverage as possible?

My test cases for my isValid file covered everything. I wanted to leave some for others to do if they decided so I left spots in the other files.

##GitHub

Also, I was required to create a testing suite for GitHub - this way, anyone who wants to submit a pull request has to pass my tests! 

![lab8_5](https://dev-to-uploads.s3.amazonaws.com/i/cs0iz0hxfxvgw9ejasx5.png)

Above is my YAML file. It's pretty straightforward and just runs my test command upon upload. I used the boilerplate settings for GitHub Actions and I think I'll expand on it in the future.

##A Stranger's Tests

My [partner's](https://github.com/StellaJung-Student) repo wasn't wholly different, and she used the same framework for testing (Jest) so I knew some of the syntaxes. There were marked differences though like that she used mock functions and I wasn't quite sure how they worked. So it took a little acclimation but once I found some work to do I got to it. Her regular program was different too and I don't think I realized how difficult it is to immerse yourself in a different code base and anticipate the 
outputs from my testing inputs.

##What I learned

So firstly, I have done testing a bit. I created tests for MHTimer and Telescope respectively so I'm not a stranger to tests.

However, working on my own tests gives me a sense of productivity that I hadn't realized before. It's really nice to set up and let grow as a project within the project.

I really like developing tests and think that it also helps me acclimate to other code bases and I for sure will do it in the future, especially for features and bugfixes I write.