The document discusses Test Driven Development (TDD) in React, explaining its iterative workflow that involves writing unit tests before coding. It emphasizes the importance of software testing, provides examples of unit tests, and describes how to implement TDD using tools like Jest and Enzyme. The document also highlights the benefits of TDD, such as improved design and code quality, and encourages practicing coding through exercises like code katas.
Quick survey ✋ Raiseyour hand if you wrote code today ✋ Keep your hand raised if you wrote unit tests ✋ Keep your hand raised if you did TDD
3.
Overview ● What issoftware testing ● The tools I use ● What is TDD (Test Driven Development) ● Example of TDD ● Take away
4.
What is softwaretesting? Software testing is an empirical technical investigation conducted to provide stakeholders with information about the quality of the product or service under test Kaner, Cem (November 17, 2006). Exploratory Testing (PDF). Retrieved from http://www.kaner.com/pdfs/ETatQAI.pdf
5.
Testing levels Ham Vocke(26 February 2018). The Practical Test Pyramid. Retrieved from https://martinfowler.com/articles/practical-test- pyramid.html
6.
Reasons for writingunit tests ● Ensure expected behavior ● Serves as documentation ● Automated regression
it("Caption is set",() => { const caption = 'test'; const wrapper = shallow( <AwesomeButton caption={caption} /> ); expect(wrapper.text()).toEqual(caption); }); Example unit test
9.
What is TestDriven Development? It is an iterative programming workflow whereby you write a single unit test and then write the code, if required, to make the test pass. When the test passes you refactor your code, including the tests, before writing the next test.
// AwesomeButton.test.tsx describe('AwesomeButton testsuite', () => { it('Environment works', ()=> {}) }); PASS src/awesomebutton.test.tsx AwesomeButton test suite ✓ Environment works (2ms) Test Suites: 1 passed, 1 total
20.
import * asReact from 'react'; import { shallow } from "enzyme"; import { AwesomeButton } from "./AwesomeButton"; describe("AwesomeButton test suite", () => { it("Renders", () => { shallow(<AwesomeButton />); }); }); FAIL src/AwesomeButton.test.tsx > 4 | import { AwesomeButton } from "./AwesomeButton"; | ^
21.
// AwesomeButton.tsx import *as React from 'react'; export function AwesomeButton() { return <button />; } PASS src/awesomebutton.test.ts AwesomeButton test suite ✓ Renders (5ms) Test Suites: 1 passed, 1 total
22.
it("Caption is set",() => { const caption = 'test'; const wrapper = shallow( <AwesomeButton caption={caption} /> ); expect(wrapper.text()).toEqual(caption); }); ✕ Caption is set (5ms) ● AwesomeButton test suite › Caption is set expect(received).toEqual(expected) // deep equality Expected: "test" Received: ""
23.
interface AwesomeButtonProps { caption?:string; } export function AwesomeButton(props: AwesomeButtonProps) { return <button>{props.caption}</button>; } ✓ Caption is set (2ms)
24.
it("onClick handler works",() => { const mockClick = jest.fn(); const wrapper = shallow( <AwesomeButton onClick={mockClick} /> ); wrapper.simulate('click'); expect(mockClick).toHaveBeenCalledTimes(1); }); ✕ onClick handler works (47ms) ● AwesomeButton test suite › onClick handler works expect(jest.fn()).toHaveBeenCalledTimes(expected) Expected number of calls: 1 Received number of calls: 0
it("Clicking with nohandler does not raise errors", () => { const wrapper = shallow( <AwesomeButton /> ); wrapper.simulate('click'); }); ✓ Clicking with no handler does not raise errors
it("Caption is set",() => { const caption = 'test'; const wrapper = shallow( <AwesomeButton caption={caption} /> ); const captionContainer = wrapper .find('[data-awesomebutton="caption"]'); expect(captionContainer.text()).toEqual(caption); }); ✕ Caption is set (44ms) ● AwesomeButton test suite › Caption is set Method “text” is meant to be run on 1 node. 0 found instead. 16 | const captionContainer = wrapper 17 | .find('[data-awesomebutton="caption"]'); > 18 | expect(captionContainer.text()).toEqual(caption); | ^
29.
export function AwesomeButton(props:AwesomeButtonProps) { return <button onClick={props.onClick}> <span data-awesomebutton='caption'> {props.caption} </span> </button>; } ✓ Caption is set (2ms)
30.
» npm test-- --coverage PASS src/AwesomeButton.test.tsx AwesomeButton test suite ✓ Renders (5ms) ✓ Caption is set (5ms) ✓ onClick handler works (2ms) ✓ Clicking with no handler does not raise errors -------------------|----------|----------|----------|----------|-------------------| File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s | -------------------|----------|----------|----------|----------|-------------------| All files | 100 | 100 | 100 | 100 | | AwesomeButton.tsx | 100 | 100 | 100 | 100 | | -------------------|----------|----------|----------|----------|-------------------| Test Suites: 1 passed, 1 total Tests: 4 passed, 4 total Snapshots: 0 total Time: 3.607s
31.
Advantages ● It feelsstrangely natural ● It can up your engagement ● It’s a good way to pick up an old toolset ● It’s a great way to learn a new language ● It improves design ● It improves estimates ● It’s excellent for pair programming ● When your feature is done, so are your tests
32.
Practice A code katais an exercise in programming which helps programmers hone their skills through practice and repetition. 🔍 TDD code kata javascript
33.
Take this withyou ● Testing is as important as the feature ● Test code is as important as feature code ● TDD is about iterative programming ● TDD may make you a better programmer ● Practice ● Be pragmatic