Skip to content

Commit

Permalink
some progress here
Browse files Browse the repository at this point in the history
  • Loading branch information
Kent C. Dodds committed Apr 16, 2018
1 parent 6259787 commit 5d7050b
Show file tree
Hide file tree
Showing 19 changed files with 431 additions and 38 deletions.
32 changes: 27 additions & 5 deletions INSTRUCTIONS.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ through it on your own if you like.
* [What types of testing are there?](#what-types-of-testing-are-there-1)
* [What's a test](#whats-a-test-1)
* [Intro to Jest](#intro-to-jest)
* [Testing a React Component](#testing-a-react-component)
* [Configuring Jest](#configuring-jest)
* [Unit testing components](#unit-testing-components)
* [Effective Snapshot Testing](#effective-snapshot-testing)
Expand All @@ -39,9 +40,10 @@ through it on your own if you like.
* [End-to-end testing](#end-to-end-testing)
* [Write tests. Not too many. Mostly integration.](#write-tests-not-too-many-mostly-integration-1)
* [Shared Content](#shared-content)
* [What's a test](#whats-a-test-2)
* [What types of testing are there?](#what-types-of-testing-are-there-2)
* [Jest](#jest)
* [Code Coverage](#code-coverage)
* [Code Coverage](#code-coverage)
* [Write tests. Not too many. Mostly integration.](#write-tests-not-too-many-mostly-integration-2)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->
Expand Down Expand Up @@ -284,23 +286,43 @@ See below in the shared content
* Configure Cypress for a web application
* Write E2E (end-to-end) tests with Cypress

### What's a test
### What types of testing are there?

See below in the shared content

### What types of testing are there?
### What's a test

See below in the shared content

> NOTE: This is duplicate content from the practices and principles workshop
> In this one however, folks should just watch the instructor go through things
> to make time for the rest of the content and not bore those who have already
> gone through this material.
See below in the shared content

### Intro to Jest

See below in the shared content

### Testing a React Component

**Instruction**:

* Nothing much here, direct people to the exercise and inform them they can
use the solution for reference

**Exercise**:

* Start the simple react tests in watch mode with `npm run test:react`
* Open `other/simple-react/item-list.js` and `other/simple-react/__tests__/item-list.todo.js`
* Follow the instructions to test the component

**Takeaways**

* The key here is to render the component and assert on the output.
* Assuming this were the only component for your entire application, attempt to
use it the way the user would and let that inform your decisions of how you
test it.

### Configuring Jest

**New Things**:
Expand Down
2 changes: 1 addition & 1 deletion client/src/__tests__/app.login.todo.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ test('login as an existing user', async () => {
// 3. Change submitted from `false` to `true`
// 4. And you're all done!
/*
http://ws.kcd.im/?ws=Testing&e=login.step-3&em=
http://ws.kcd.im/?ws=Testing&e=app.login&em=
*/
test.skip('I submitted my elaboration and feedback', () => {
const submitted = false // change this when you've submitted!
Expand Down
148 changes: 148 additions & 0 deletions client/src/components/__tests__/__snapshots__/login.step-4.js.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`snapshot 1`] = `
.css-0,
[data-css-0] {
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
flex-direction: column;
align-items: center;
width: 100%;
min-width: 200px;
max-width: 400px;
margin-left: -116px;
-webkit-box-orient: vertical;
-webkit-box-direction: normal;
-webkit-flex-direction: column;
-webkit-box-align: center;
-webkit-align-items: center;
}
.css-1,
[data-css-1] {
display: grid;
grid-template-columns: 100px 1fr;
grid-gap: 16px;
font-size: 18px;
align-items: center;
margin-top: 30px;
margin-bottom: 30px;
width: 100%;
-ms-grid-template-columns: 100px 1fr;
-ms-grid-gap: 16px;
-webkit-box-align: center;
-webkit-align-items: center;
}
.css-2,
[data-css-2] {
background: white;
height: 50px;
border: none;
border-radius: 10px;
box-shadow: var(--shadow);
border-bottom: 5px;
width: 100%;
min-width: 150px;
display: block;
padding-left: 10px;
}
.css-2::-webkit-input-placeholder,
[data-css-2]::-webkit-input-placeholder {
opacity: 0.5;
}
.css-2::-moz-placeholder,
[data-css-2]::-moz-placeholder {
opacity: 0.5;
}
.css-2::-ms-input-placeholder,
[data-css-2]::-ms-input-placeholder {
opacity: 0.5;
}
.css-2::placeholder,
[data-css-2]::placeholder {
opacity: 0.5;
}
.css-7,
[data-css-7] {
font-size: 13px;
font-family: Raleway,sans-serif;
background: var(--green);
padding: 10px 20px;
display: block;
margin-left: auto;
color: white;
border: none;
border-radius: 10px;
box-shadow: var(--shadow);
cursor: pointer;
transition: 0.5s;
-webkit-transition: 0.5s;
-moz-transition: 0.5s;
}
.css-7:hover,
[data-css-7]:hover {
box-shadow: var(--shadowHover);
}
@media only screen and (max-width: 819px) {
.css-0,
[data-css-0] {
margin-left: 0;
width: 90%;
}
}
<div>
<div
style="display: flex;"
>
<form
class="css-0"
>
<div
class="css-1"
>
<label
for="username-input"
>
Username
</label>
<input
class="css-2"
id="username-input"
name="username"
placeholder="Username..."
/>
<label
id="password-input"
>
Password
</label>
<input
aria-labelledby="password-input"
class="css-2"
name="password"
placeholder="Password..."
type="password"
/>
</div>
<button
class="css-7"
type="submit"
>
Submit
</button>
</form>
</div>
</div>
`;
20 changes: 12 additions & 8 deletions client/src/components/__tests__/login.final.js
Original file line number Diff line number Diff line change
@@ -1,29 +1,33 @@
import React from 'react'
import {generate, render, Simulate} from 'til-client-test-utils'
import {
generate,
renderIntoDocument,
cleanup,
render,
} from 'til-client-test-utils'
import Login from '../login'

afterEach(cleanup)

test('calls onSubmit with the username and password when submitted', () => {
// Arrange
const fakeUser = generate.loginForm()
const handleSubmit = jest.fn()
const {container, queryByLabelText, queryByText} = render(
const {getByLabelText, getByText} = renderIntoDocument(
<Login onSubmit={handleSubmit} />,
)

const usernameNode = queryByLabelText('username')
const passwordNode = queryByLabelText('password')
const formNode = container.querySelector('form')
const submitButtonNode = queryByText('submit')
const usernameNode = getByLabelText('username')
const passwordNode = getByLabelText('password')

// Act
usernameNode.value = fakeUser.username
passwordNode.value = fakeUser.password
Simulate.submit(formNode)
getByText('submit').click()

// Assert
expect(handleSubmit).toHaveBeenCalledTimes(1)
expect(handleSubmit).toHaveBeenCalledWith(fakeUser)
expect(submitButtonNode.type).toBe('submit')
})

test('snapshot', () => {
Expand Down
8 changes: 4 additions & 4 deletions client/src/components/__tests__/login.step-2.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ test('calls onSubmit with the username and password when submitted', () => {
// Arrange
const fakeUser = generate.loginForm()
const handleSubmit = jest.fn()
const {container, queryByLabelText, queryByText} = render(
const {container, getByLabelText, getByText} = render(
<Login onSubmit={handleSubmit} />,
)

const usernameNode = queryByLabelText('username')
const passwordNode = queryByLabelText('password')
const usernameNode = getByLabelText('username')
const passwordNode = getByLabelText('password')
const formNode = container.querySelector('form')
const submitButtonNode = queryByText('submit')
const submitButtonNode = getByText('submit')

// Act
usernameNode.value = fakeUser.username
Expand Down
6 changes: 4 additions & 2 deletions client/src/components/__tests__/login.step-2.todo.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import React from 'react'
import ReactDOM from 'react-dom'
// you'll need these:
// import {generate, render, Simulate} from 'til-client-test-utils'
// note that til-client-test-utils is found in `client/test/til-client-test-utils`
// and it re-exports some utilities from react-testing-library (like render and Simulate)
import Login from '../login'

test('calls onSubmit with the username and password when submitted', () => {
Expand All @@ -11,7 +13,7 @@ test('calls onSubmit with the username and password when submitted', () => {
const handleSubmit = jest.fn()
// use: render(<Login onSubmit={handleSubmit} />)
// It'll give you back an object with
// `queryByLabelText` and `queryByText` functions
// `getByLabelText` and `getByText` functions
// so you don't need a div anymore!
const div = document.createElement('div')
ReactDOM.render(<Login onSubmit={handleSubmit} />, div)
Expand Down Expand Up @@ -44,7 +46,7 @@ test('calls onSubmit with the username and password when submitted', () => {
// 3. Change submitted from `false` to `true`
// 4. And you're all done!
/*
http://ws.kcd.im/?ws=Testing&e=login.step-2&em=
http://ws.kcd.im/?ws=Testing&e=login.step-2%20(react-testing-library)&em=
*/
test.skip('I submitted my elaboration and feedback', () => {
const submitted = false // change this when you've submitted!
Expand Down
28 changes: 28 additions & 0 deletions client/src/components/__tests__/login.step-3.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from 'react'
import {generate, renderIntoDocument, cleanup} from 'til-client-test-utils'
import Login from '../login'

// If you render your components with renderIntoDocument via react-testing-library
// then you can get automatic cleanup of any components rendered like this:
afterEach(cleanup)

test('calls onSubmit with the username and password when submitted', () => {
// Arrange
const fakeUser = generate.loginForm()
const handleSubmit = jest.fn()
const {getByLabelText, getByText} = renderIntoDocument(
<Login onSubmit={handleSubmit} />,
)

const usernameNode = getByLabelText('username')
const passwordNode = getByLabelText('password')

// Act
usernameNode.value = fakeUser.username
passwordNode.value = fakeUser.password
getByText('submit').click()

// Assert
expect(handleSubmit).toHaveBeenCalledTimes(1)
expect(handleSubmit).toHaveBeenCalledWith(fakeUser)
})
Loading

0 comments on commit 5d7050b

Please sign in to comment.