На трон инструментов автоматизации функциональных испытаний появилась новая претензия: Cypress.io . Cypress быстр? Да. Является ли Cypress интерактивным? Ага. Надежен ли Cypress? Вы ставите. И лучше всего … это круто!
Но является ли Cypress альтернативой Selenium WebDriver ? Неужели Selenium, нынешний король фреймворков для веб-автоматизации и тестирования, съеживается из-за страха за свою позицию или доброжелательно улыбается предполагаемому узурпатору, прекрасно зная, что это просто ребенок!
Cypress лучше, чем Selenium WebDriver? Меня часто спрашивают об этом. И, честно говоря, самый простой путь статьи «это против того» — попытаться выяснить, что «лучше». Но я не пойду по этому пути. Вместо этого я попытаюсь объяснить, чем Cypress отличается от Selenium WebDriver.
Описывая разницу между Cypress и Selenium WebDriver, вы сможете понять, как работает Cypress. В этом посте также будет попытаться объяснить, почему Cypress избрал путь к автоматизации веб-браузера, путь, который заметно отличается от пути WebDriver.
Чем Cypress похож на Selenium WebDriver? Они контролируют и автоматизируют веб-браузер, что позволяет вам создавать функциональные тесты, которые имитируют действия, которые выполняет пользователь, и проверять правильность результатов. Но на этом сходство заканчивается, и начинаются различия. Надеемся, что знание различий между этими двумя инструментами тестирования и понимание причин этих различий помогут вам выбрать, какой инструмент использовать и когда.
Давайте начнем исследовать эти различия.
Это для разработчиков внешнего интерфейса!
Selenium WebDriver был создан для сквозных регрессионных тестов веб-приложений. Среда внешнего тестирования Selenium в основном используется разработчиками QA, а не разработчиками. Это потому, что идея разработчиков переднего плана, тестирующих свой собственный код, не распространена.
Но небольшая революция начинает происходить в мире веб-разработчиков. Фронтенд-разработчики начинают писать собственные тесты. Да, они принимают вызов гибких методологий программного обеспечения . Они понимают, что без написания собственных тестов гибкая разработка невозможна. Они пишут юнит-тесты, а также интеграцию и, да, комплексные функциональные тесты, которые проверяют свой интерфейс с помощью реальных браузеров, точно так же, как тесты автоматизации, которые пишут разработчики QA. Движение « Сдвиг влево » имеет много этих тенденций.
Потребности разработчиков веб-интерфейса в сквозных тестах отличаются от потребностей разработчиков QA. Разработчикам веб-интерфейса не требуется промежуточная среда, в которой развернуты веб-интерфейс приложения, серверная часть и системы баз данных. Они могут обойтись только с частью внешнего интерфейса, работающей локально, и довольно легко издеваться над бэкэндом .
Этот факт — целевая аудитория Cypress — внешние разработчики — лежит в основе всех различий между Cypress и WebDriver. Это разные инструменты для разных пользователей.
Это только JavaScript!
Веб-разработчики веб-интерфейса пишут только на одном языке — JavaScript . Это единственный язык, который могут исполнять браузеры, и поэтому у них нет другого выбора. Это ограничение имеет свои недостатки и недостатки, но факт существует — существует только один язык для разработчиков внешнего интерфейса ( несмотря на такие варианты, как TypeScript ).
И поскольку Cypress предназначен для разработчиков веб-интерфейсов, тесты Cypress могут быть написаны только на JavaScript. Другие языки не поддерживаются. Сравните это с Selenium WebDriver, у которого есть API со многими привязками языка , включая Java, C #, Python, Ruby, R, Dart, Objective-C и, да, JavaScript.
Так что помните — если вы хотите провести Cypress-тестирование, вам придется выучить JavaScript. Что здорово, потому что JavaScript сегодня — это не JavaScript ваших бабушек и дедушек. Это современный, мощный и лаконичный язык, который широко используется сегодня и имеет самый большой в мире репозиторий пакетов с открытым исходным кодом (), репозиторий кода, который несколько лет назад обогнал то, что раньше было самым большим репозиторием — репозиторием.
Это только мокко!
Cypress не только ограничивает вас языком, на котором вы можете писать, но также ограничивает используемую среду тестирования. Mocha — это среда тестирования, с которой вы пишете свои тесты (роль среды тестирования в JavaScript аналогична роли JUnit в Java или NUnit в C #). Вы не можете писать свои тесты в другой среде JavaScript, такой как Jest или Tape .
Selenium WebDriver, с другой стороны, не навязывает вам среду тестирования. Более того, вам даже не нужно использовать среду тестирования. Вы можете написать обычную программу, которая не является тестом, программу, которая просто управляет браузером. Многие проекты используют WebDriver таким образом, например, для сканирования веб-страниц и сбора информации.
Но Cypress рано решил, что он посвящен задаче написания тестов веб-интерфейса и может использоваться только в рамках тестирования, и что основой тестирования ДОЛЖЕН быть Mocha.
Уже достаточно. Покажите мне какой-нибудь кипарис-код!
«Хорошо, хорошо, я понял», я слышу, как вы говорите. Но вы можете , пожалуйста , покажите мне тест Cypress , так что все это будет немного менее абстрактным? Конечно, держи:
'use strict'
describe(`TodoMVC using Cypress`, function () {
it('can add todos and then delete them', () => {
cy.visit('http://todomvc.com/examples/react/#/')
cy.get('.new-todo').type('Cook dinner{enter}')
cy.get('.view > label').should('have.text', 'Cook dinner')
cy.get('.new-todo').type('Clean house{enter}').then(() => {debugger})
cy.get('.view > label').eq(1).should('have.text', 'Clean house')
cy.get('.toggle').eq(1).click()
cy.contains('1 item left').should('exist')
cy.contains('Clear completed')
})
})
Как видите, здесь есть примеры команд и утверждений Cypress.
cy.visit заставит браузер перейти по указанному URL.
cy.get вернет ссылку на рассматриваемый элемент, на котором вы можете либо напечатать, щелкнуть, либо проверить утверждения об использовании содержимого и другие утверждения.
Как вы можете видеть, на первый взгляд, он удивительно похож на Selenium Webdriver, хотя и проще, и с гораздо большей мощностью.
Это только Chrome!
Cypress Test Runner работает только на Chrome. Он не поддерживает Firefox, Safari, Edge или IE. Это может стать шоком для разработчиков QA, которые привыкли к удивительной поддержке WebDriver всех этих браузеров. Но да, Cypress — это только Chrome. Существует проблема, которая была открыта для кросс-браузерной поддержки , но этой проблеме уже почти год. Приоритеты Кипариса, кажется, лежат в другом месте.
Почему веб-разработчики хотят запускать свои тесты только в Chrome? Я считаю, что есть несколько ответов на этот вопрос. Во-первых, различия между Chrome, Firefox, Safari и Edge в наши дни невелики и становятся все меньше и меньше для большинства приложений. Поэтому проверка только в Chrome, вероятно, достаточно хороша при тестировании в разработке.
Во-вторых, выполнение всех тестов во всех браузерах требует времени , и разработчики внешнего интерфейса, как мы уже говорили выше, не хотят ждать своих тестов.
В-третьих, у многих компаний есть разработчики QA, которые проводят сквозные тесты во всех браузерах, и поэтому они в порядке, так как очень редкая ошибка время от времени проскальзывает и обнаруживается командой QA. И компании, которые не имеют обширные кросс-браузерные тесты? Тогда они в порядке с теми же редкими ошибками, которые проскальзывают и доходят до пользователей время от времени.
В- четвертых, разработчики внешних интерфейсов делают уход, и хотел бы кипарис поддерживать больше браузеров, но это просто не приоритет для них, учитывая причины , описанные выше.
Это работает в браузере!
Помимо того, что разработчики веб-интерфейса привыкли к JavaScript, есть и другая причина, более техническая, что поддерживается только JavaScript.
Код, который вы пишете в своих тестовых сценариях Cypress, не запускается вне браузера, как в WebDriver. Он запускает браузер. Это то, что выполняет ваш тестовый код. Фактически, он выполняет ваш тестовый код и код приложения, которое вы тестируете!
Когда вы запускаете тест, происходит следующее: во-первых, Cypress подготовит ваш код для запуска в браузере (технически говоря, он объединит все модули в вашем коде в один файл JS с помощью веб-пакета ). Когда все будет готово, он запустит Chrome и вставит ваш тестовый код в пустую страницу. Затем он запустит этот тестовый код в браузере.
Этот тестовый код в первую очередь переходит на страницу приложения (используя `cy.navigate (‘ http: // localhost: 8080 ‘)`), которая запускается в. Cypress заставит iframe перейти на эту страницу, но ваш код работает в браузере, и (несколько волшебно) имеет доступ к тому же, что и этот iframe, и поэтому все команды, такие как «click» или «type», происходят внутри браузер, использующий обычный.
Для сравнения давайте рассмотрим архитектуру Selenium WebDriver и ее значение для выполнения тестов Selenium. Посмотрите на диаграмму ниже.
С Selenium WebDriver у вас есть три процесса:
- Selenium WebDriver
- Драйвер браузера, такой как ChromeDriver , GeckoDriver (для Firefox), EdgeDriver , SafariDriver и т. Д.
- The browser itself
All the communications between these processes means that Selenium tests take a long time to run. Which takes us to our next point:
It’s Fast!
This in-browser execution is at the basis of the speed of Cypress testing. With Cypress, you have just one process: the browser itself. With Cypress, your test code is running alongside your application code.
So an automation command (e.g., clicking a button) does not send the command to the browser like WebDriver does through out-of-process communication. Instead, Cypress uses DOM events to send a click command to the button. Much MUCH faster.
And while WebDriver’s out of process automation involves asynchronous communication, Cypress’ automation commands are mostly synchronous and in-memory. This generates extremely fast tests.
I believe that it is this speed that is the main reason that frontend developers are enamored with Cypress. WebDriver, at least perception-wise, did not give them the speed that they needed. Frontend developers want to run their tests ALL THE TIME, and cannot afford the luxury of a suite that takes tens of minutes to run. They want to run their suite, and they need it to run in a minute or two, not more.
Is this speed difference really substantial as Cypress’ documentation claims? From my admittedly small experiments, then yes, but I am not convinced that the difference is worth the other benefits WebDriver has. Try it yourself on a small sample of tests, and see for yourself!
It Has Built-In Server Mocking!
But there is another reason that Cypress is perceived as faster. Let’s remind ourselves that Cypress is meant for frontend developers. Let’s also remind ourselves that frontend developers sometimes don’t use the real backend, but rather mock the XML HttpRequests to the server. This makes for extremely fast tests, on the order of seconds, regardless of whether you use Cypress or Selenium WebDriver.
Cypress understands that, and has built-in facilities for mocking server responses, facilities that are crucial for their target audience: frontend developers. Selenium WebDriver has no facilities for that, and to mock server responses, a WebDriver tests would need to run a mock server that returns the correct responses. While possible, it is a slower and much less convenient option: a fast and in-memory facility for mocking will always outperform a slow out of process one.
And it’s not only the speed of execution. The convenience of a built-in facility for mocking servers cannot be overstated in terms of speed of writing the tests. The fact that each test explicitly describes the mock responses is much easier to code (and understand!) than a separate server program that mocks the same responses.
It Has a Bizarre Execution Model!
Yeah, I know. Weird heading for this section. But it does! Cypress’ execution model is bizarre! To prove it, let me show you some Cypress sample code:
describe(`TodoMVC using Cypress`, function () {
it('can add todos and then delete them', () => {
// visit the todomvc application
cy.visit('http://todomvc.com/examples/react/#/')
// type a new todo into the "new todo" input field.
cy.get('.new-todo').type('Cook dinner{enter}')
// ensure that a new todo was created correctly
cy.get('.view > label').should('have.text', 'Cook dinner')
// Add another todo and asser that it was added to.
cy.get('.new-todo').type('Clean house{enter}').then(() => {debugger})
cy.get('.view > label').eq(1).should('have.text', 'Clean house')
// now check the toggle, to make it "done".
cy.get('.toggle').eq(1).click()
cy.contains('1 item left').should('exist')
})
})
“That’s not bizarre!”, you say, and you would be right if it did what you thought it did. But it doesn’t. When you call `cy.click` or `cy.navigate` or `cy.type`, you’re not executing that command. You’re actually recording what you want done when Cypress does run the test. The test doesn’t run inside the `it` function. It runs after the `it` function ends, based on the commands you recorded. `cy.nagivate/click/type` don’t execute, but rather record, to be replayed later.
What are the practical consequences of that decision for the developer? If you want to branch your code based on a value in the page, you can’t. For example, let’s say you want to do something like this, to execute some test code based on the value of text on the page:
const countItemsLeft = cy.contains('item left')
if (countItemsLeft.innerText === '1 items left') {
// do something...
}
This won’t work. Because when running the test, you’re not actually executing the automation commands, and so checking for the value of the text is irrelevant.
Cypress does support this kind of test, but in a byzantine way:
cy.contains('item left')
// do the following code on the element that contains "item left".
.then(countItemsLeft => {
// if the text in the element is "1 items left", log it.
if (countItemsLeft.innerText === '1 items left') {
console.log('lalala!')
}
})
The `.then` facility enables you to supply code that «really» runs when Cypress executes the automation commands. This `.then` solves the problem of branched test execution in a «record-then-execute» model, but would not have been needed if Cypress had followed a regular execution model like WebDriver does.
So why does Cypress have this byzantine execution model? The answer to that lies in the next section.
It’s Less Flaky!
According to Cypress, by delegating execution commands like navigate, click, and type, to Cypress itself, Cypress enables more control on how to execute those commands. It can, for example, when asked to click on a button, wait for that button to appear on the screen, stop animation, and then, and only then will it click it.
According to Cypress, this results in much less flaky tests.
I’m not convinced.
Waiting for an element to appear sounds a lot like WebDriver’s implicit wait, so I’m not sure why Cypress believes it is better in that regard.
But I do believe Cypress is less flaky, but this has nothing to do with controlling the execution. Because the tests on it are executed frontend only, with a mocking of all server responses, the test runs very fast. And the faster a browser test runs, the less flaky it is.
So, yes, I believe that Cypress is less flaky, but not because of control of execution. Too bad, the byzantine method of execution detracts somewhat from this wonderful tool.
But I may be wrong!
It’s Interactive!
One of the biggest coolnesses that Cypress has is also a big part of the reasons lots of developers flock to it: it’s an IDE of sorts. Because Cypress fully controls the execution environment (the browser), it can give developers a more interactive experience:
As you can see in the screenshot, when the test runs, the commands that are executed are shown in the side panel, while they are being executed. Moreover, once the test ends, you can click on each command in the side panel, and you can see a screenshot of how the page looked like when the command was executing. This is called Time traveling.
This is phenomenal for debugging a test! Cypress screenshots and seeing how your tests progress is a marvelous way to debug the tests, and a marvelous way to start to understand why the test failed. The whole experience helps in writing, understanding, and debugging tests, and in analyzing their results.
Its Documentation Is Excellent!
Compare Cypress’ documentation…
When you review Cypress documentation, it looks a lot nicer. But it’s not just what the documentation looks like. Cypress’ documentation is much more in-depth and broad. It covers most of what you want to know, without the need to go looking elsewhere on the web. You can see that the developers spent a lot of time on the documentation itself. Kudos to them, as it enhances the experience in a significant manner.
Selenium’s documentation is pretty good, especially given that it has a much more wider net to throw—both because it is multi-language, and because it is multi-browser. Unfortunately, it carries with it the weight of previous years and is not equal to Cypress’, both in depth and in width.
Conclusion
As you can see, on the surface, although the two tools Cypress and Selenium WebDriver—seem similar, there are actually many differences between the two. The main reason for the differences, in my opinion, stem from the different requirements from the two tools: Selenium was built as a multi-language, cross-browser tool, that fits multiple purposes, not just testing. Cypress, on the other hand, was built for one thing, and one thing only, executing frontend developers tests fast and consistently.
That is why Cypress seems so limited: it supports just one language (JavaScript), one framework (Mocha), and one browser (Chrome). Selenium WebDriver does not have these limitations. It cannot have these limitations because it is a general purpose tools for multiple target audiences. But these limitations are mostly not a problem for frontend developers, and enable Cypress to give frontend developers the advantages that they do need: speed and consistency.
Cypress is a classic example of less is more, while Selenium WebDriver is a classic example of a Swiss Army knife.
Which is better for you: Cypress or Selenium? You tell me in the comments!
One thing I do know is that my company, Applitools, has SDKs and tutorials for how to do visual UI testing with Cypress and Selenium. So whichever you choose for test automation, we got you covered.