Skip to content

Commit a797933

Browse files
committed
add updated draft upto r2.1 for module 5
1 parent 55e87d8 commit a797933

File tree

20 files changed

+670
-441
lines changed

20 files changed

+670
-441
lines changed

module5-testing/assets/README.md

Lines changed: 0 additions & 2 deletions
This file was deleted.
8.54 KB
Loading

module5-testing/assets/pyramid2.jpeg

23.7 KB
Loading
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
# Introduction to testing
2+
3+
We are now moving into the advanced concepts of backend web development. However, at this point of the bootcamp these concepts should not be completely unfamiliar to you either. You have seen what tests look like and how they're executed in all your previous assignments. Now it's time to understand them in detail. The objectives of this lesson are:
4+
1. Understanding tests and their importance
5+
2. Getting familiar with the syntax of test code
6+
7+
## What is a test?
8+
9+
In programming, a test refers to a piece of code that can be run to verify the
10+
behavior of a program. For example, if you write a function, and you want to be
11+
sure that it works for various inputs and outputs, you can write a test for this
12+
function.
13+
14+
Tests themselves are also code. At larger companies, every piece of submitted code
15+
needs to submitted with a corresponding test. A general rule of thumb is that,
16+
if by mistake you change a line of your code so that the behavior is wrong, a test
17+
somewhere should fail, so that such a mistake can be caught.
18+
19+
Tests are an important part of many companies' infrastructure for development.
20+
Generally, humans are not manually running these tests, though you may manually
21+
run some tests before sending a pull request or while working on the test itself. In a process called **continuous integration** (CI), these tests will usually automatically run after every pull request is proposed. This means that generally, if your code and pull request are not passing the tests, it cannot be merged in until fixed.
22+
23+
There are many types of tests: unit tests, integration tests, smoke tests,
24+
and so on. In a later section, we will talk about some of these types of tests.
25+
Most commonly, we will refer to unit tests, which are the most frequent type of
26+
tests.
27+
28+
## Why is testing important?
29+
30+
You may think it is sufficient simply to manually test your code.
31+
32+
There are a few reasons testing is very important when it comes to a growing
33+
codebase. You should not imagine the situation where you are working on a
34+
project with one or two people, but a situation where you are working with a
35+
larger team and with a codebase that the company will use even long after you leave. You
36+
may not be at the company five years later, or you may at times forget what the code does
37+
in six months. This is where tests come in to make developers' lives easier as it mainly helps to catch bugs in time and hold us accountable towards high quality error-free code.
38+
39+
### Correctness
40+
Most obviously, a test is used to verify the correctness of the code. If you
41+
have ever changed your code then had to test three or more cases manually, then
42+
you are familiar with the fact that it is quite cumbersome to repeatedly check
43+
manually. Not only that, it's very easy to forget to check some case when a
44+
human is doing it by hand.
45+
46+
In contrast, when you write a test, you simply need to run a command in order to
47+
initiate the tests again, rather than repeating some steps to ensure that your
48+
code is working.
49+
50+
If you work at a company with a practice of code reviews, consider the perspective of the
51+
person reviewing your code: How do they know your code doesn't have bugs? How do
52+
they know it works correctly? If your code is submitted along with tests, the
53+
reviewer can be aware of exactly what you have or haven't verified about your
54+
code.
55+
56+
### Ease of change
57+
Have you ever felt scared to change code, because you weren't sure if it would still work for all the cases after you changed it? With a good test suite, this fear generally
58+
doesn't exist. Even if the code is rewritten but the same tests pass, indicating
59+
that the new code has the same behavior, one can feel a lot more secure about
60+
rewriting the code.
61+
62+
Having good tests allows code to be changed in a more robust fashion. When the
63+
same tests pass, a developer can be more sure (perhaps not completely sure,
64+
depending on the tests) that changing the code did not break anything.
65+
Additionally, it allows people who are not familiar with the code (say, your
66+
teammates who work on related code, or someone who is responsible for your code
67+
five years later) to more easily work with the code.
68+
69+
### Documentation
70+
A well-written test suite serves as documentation. Again, imagine you have just
71+
joined a company, and you don't know what a function or file does. In fact, if you want to understand what a piece of code does, it's often more productive to go read the
72+
tests first, rather than the code itself. You must have done this while working on your assignments from previous modules.
73+
74+
In the next section, we'll look at an example of a test, which will help illustrate how the tests themselves can be used to document the code.
75+
76+
## Example code
77+
78+
Let's now take a look at some example code for tests. Even if you don't know much about testing frameworks, you'll find that tests are actually quite readable anyway.
79+
80+
Let's take a look at this example from [Jest](https://jestjs.io), one of the most popular testing frameworks in JavaScript. Most testing frameworks work in approximately the same fashion, simply using different syntax.
81+
82+
```js
83+
test('adds 1 + 2 to equal 3', () => {
84+
expect(sum(1, 2)).toBe(3);
85+
});
86+
```
87+
88+
What does this test do? -- To start off, consider what a function called `sum`
89+
should do. Even though we can't see the implementation, this is an example of
90+
how simply reading the test can tell you how the function should behave.
91+
92+
In this test, when the sum function is given the arguments `sum(1, 2)`, we call
93+
a function `expect` and assert the result `toBe` `3`. Even above that, there is
94+
a descriptive string (anything can be written there), that tells us that the test checks for `adds 1 + 2 to equal 3`. Again, even though we have no idea how sum is written internally (although in this case, writing such a function should be quite trivial), **only from reading the test**, the behavior of the function is documented in some fashion.
95+
96+
Let's continue reading some tests, without even looking at the implementation of the tested functions for illustrative purposes.
97+
98+
In this example, let's look at the function `absolute`. You may be able to guess
99+
what the function does from the name, but if not, read the code below, and try
100+
to figure out what it does.
101+
102+
```js
103+
describe('absolute', () => {
104+
it('should return positive number if input is positive', () => {
105+
const result = absolute(1);
106+
expect(result).toBe(1);
107+
});
108+
it('should return positive number if input is negative', () => {
109+
const result = absolute(-1);
110+
expect(result).toBe(1);
111+
});
112+
it('should return zero if input is zero', () => {
113+
const result = absolute(0);
114+
expect(result).toBe(0);
115+
});
116+
});
117+
```
118+
119+
In this example, the `describe` function is used to group together a related set
120+
of tests. Note how the code almost reads like a written description of the
121+
behavior of the test.
122+
123+
Finally, let's read one more example of a slightly more complex test. Let's look at a pice of code from the tests of the Express.js Meme API assignment. Hope you haven't forgotten it yet! Even if you have or if you don't understand the specific syntax or function calls, the important part is to try to read the test and see how it helps us understand the behavior of the functionality being tested.
124+
125+
```js
126+
describe("GET /memes/filter", () => {
127+
it("responds with empty array for non-matching genre", (done) => {
128+
const genre = "random";
129+
const expectedOutput = [];
130+
request(app)
131+
.get("/memes/filter?genre=" + genre)
132+
.set("Accept", "application/json")
133+
.expect("Content-Type", /json/)
134+
.expect(200, (err, res) => {
135+
if (err) return done(err);
136+
expect(res.body).to.be.an("array");
137+
expect(res.body).to.deep.equal(expectedOutput);
138+
done();
139+
});
140+
});
141+
142+
it("responds with error message when invalid parameter is passed", (done) => {
143+
const genre = "";
144+
const expectedOutput = "invalid query parameter";
145+
request(app)
146+
.get("/memes/filter?genre=" + genre)
147+
.set("Accept", "application/json")
148+
.expect("Content-Type", /json/)
149+
.expect(400, (err, res) => {
150+
if (err) return done(err);
151+
expect(res.body).to.equal(expectedOutput);
152+
done();
153+
});
154+
});
155+
});
156+
```
157+
158+
Try to answer the following questions about the above example:
159+
* Which piece of functionality is being tested here?
160+
* How many scenarios are being tested?
161+
* What is the expected output in each scenario?
162+
163+
By reading the tests in this section, you should have a more concrete understanding of what tests may look like, how they verify correctness, and how they help others understand the behavior of a function. In the next lesson, we will understand a little more about the philosophy and mindset of testing.

module5-testing/r1-what-is-a-test/README.md

Lines changed: 0 additions & 22 deletions
This file was deleted.

0 commit comments

Comments
 (0)