Live share
WHO I AM
dmtrKovalenko
@dmtrKovalenko
Пирамида
Для кого?
Для кого?
Для кого?
Для кого?
Unit testing
Для кого?
Integration testing
Для кого?
e2e testing
e2e
Integration
Unit
Вопрос
?=
Давайте разбираться!
Где граница?
e2e
Integration
Unit
непонятно
Rest API
e2e
Front-end
Cypress.Commands.add('login', () => {
cy.visit('/login')
cy.get('#email').type('admin@cypress.io')
cy.get('#password').type('security')
cy.get('#submit-btn').click()
})
cy.login()
Cypress.Commands.add('login', () => {
cy.request('/testRoutes/loginAsAdmin')
})
Где граница?
e2e
Integration
Unit
Назад
В
Прошлое
Мы тут
React
Angular 1.0
Vue
JQuery
2006
2012
2013
2014
2019
Timeline
Testing Pyramid
2008
Google it
https://benhutchison.wordpress.com/2008/03/20/automated-testing-2-the-test-pyramid/
Почему
- Долгаааа
- Сложнааа
(запускать и писать)
(писать и поддерживать)
не e2e?
чо
так
сложно долго
Мы тут
React
Angular 1.0
Vue
JQuery
2006
2012
2013
2014
2019
Timeline
Testing 🔼
2008
2004
Selenium
Если у вас нету тестов
То билд у вас не упадет
Если вы не запускаете тесты
То у вас нету
тестов
e2e
is painfull
Build Time: 42:14
Мы тут
React
Angular 1.0
Vue
JQuery
2006
2012
2013
2014
2019
Timeline
Testing 🔼
2008
2004
Selenium
version: 2
jobs:
build:
docker:
- image: cypress/base:10
steps:
- checkout
- restore_cache:
name: Restore Yarn Package Cache
keys:
- yarn-packages-{{ checksum "yarn.lock" }}
- run:
name: Install Dependencies
command: yarn install --frozen-lockfile
- save_cache:
name: Save Yarn Package Cache
key: yarn-packages-{{ checksum "yarn.lock" }}
paths:
- ~/.cache
- run: cypress run --record
Проще не бывает
version: 2
jobs:
build:
docker:
- image: cypress/base:10
parallelism: 15
steps:
- checkout
- restore_cache:
name: Restore Yarn Package Cache
keys:
- yarn-packages-{{ checksum "yarn.lock" }}
- run:
name: Install Dependencies
command: yarn install --frozen-lockfile
- save_cache:
name: Save Yarn Package Cache
key: yarn-packages-{{ checksum "yarn.lock" }}
paths:
- ~/.cache
- run: cypress run --record
Еще и быстро
e2e
e2e
Integration
Unit
Ну-ка напиши тест
import db from './db'
const router = express.Router();
router.get('/users', (req, res) => {
db.getAllUsers().then(res.json)
})
Dependency Injection
const router = express.Router();
router.get('/users', (req, res) => {
req.db.getAllUsers().then(res.json)
})
Я
Unit tests
TRIGGERED
Rest API
Frontend
GraphQL
Overmocking
import { fetchFromApi } from '~/fetcher'
function fetchUsers() {
return fetchFromApi('/users')
}
it('Should fetch users', async () => {
jest.mock(fetchFromApi, () => Promise.resolve([{ id: 1 }]))
const result = await fetchUsers()
expect(result).toEqual([{ id: 1 }])
})
И правда
Чем больше тесты знают про реализацию, тем...
Но ведь e2e тоже не огонь
/root/div/descendant::*[not (@class='bad')] //h1/following-sibling::ul[1]
<div data-test-id="user-list-name"/>
Убираем хрупкость
e2e
One more thing
Зачем мы пишем тесты?
Зачем?
Надежность
e2e
Integration
Unit
Надежность
Скорость
>.< Бесполезные тесты
UI components unit testing
it("renders three <Foo /> components", () => {
const wrapper = shallow(
<MyComponent>
<Foo />
<Foo />
<Foo />
</MyComponent>
);
expect(wrapper.find(Foo)).to.have.lengthOf(3);
});
const Component = () => (
<MyComponent>
<Foo />
<Foo />
<Foo />
</MyComponent>
)
const jsx = React.createElement
const Component = () => jsx(
MyComponent,
null,
jsx(Foo, null),
jsx(Foo, null),
jsx(Foo, null)
);
===
UI components unit testing
it("renders three <Foo /> components", () => {
const wrapper = shallow(jsx(
MyComponent,
null,
jsx(Foo, null),
jsx(Foo, null),
jsx(Foo, null)
));
const arguments = jsx.mock.calls[0]
expect(arguments.filter((element) => element.type === Foo).to.have.lengthOf(3)
});
Text
Тестирование Реализации
vs
export function calculateUsagePeriods(
currentUsagePeriodStartsAt,
currentUsagePeriodEndsAt,
organizationCreatedAt,
n = 6
) {
if (!currentUsagePeriodStartsAt) return []
const usagePeriods = []
let startTime = moment.utc(currentUsagePeriodStartsAt)
let endTime = moment.utc(currentUsagePeriodEndsAt)
for (let i = 0; i < n; i++) {
if (endTime.isBefore(organizationCreatedAt)) {
break
}
usagePeriods.push({
startTime: startTime.clone(),
endTime: endTime.clone(),
})
startTime.subtract(1, 'month')
endTime.subtract(1, 'month')
}
return usagePeriods
}
test("Should calculate usage periods when n = 5", () => {
const result = calculateUsagePeriods(new Date(), addDays(new Date(), 5), 5)
expect(result).toEqual([...])
})
test.each`
startsAt | endsAt | n | expected
${new Date()} | ${new Date()} | ${10} | ${[15, 16]}
${new Date()} | ${addDays(new Date(), 10)} | ${6} | ${[15, 16]}
${new Date()} | ${addDays(new Date(), -10)} | ${15} | ${[15, 16]}
`(
"Should calculate usage periods when startsAt = $startsAt, endsAt = $endsAt n = $n",
({ startsAt, endsAt, n, expected }) => {
expect(calculateUsagePeriods(startsAt, endsAt, n)).toEqual(expected);
}
);
Unit Tests
But useless
Users ❤️ Quality app
Business
Dev ❤️ Coding
Dev ❤️ Create quality apps
❤️ Happy users
e2e
Integration
Unit
===
Illuminati confirmed
Links
Спасибо за внимание
Unit tests are useless
By dkovalenko
Unit tests are useless
- 1,865