Cypress Best Practices for Test Automation
On This Page What is Cypress?10 Cypress Best Practices you Need to
- What is Cypress?
- 10 Cypress Best Practices you Need to Know
- 1. Use data Attributes When Selecting Elements
- 2. Independent it () blocks
- 3. Cypress basics: before (), beforeEach (), after () and afterEach ()
- 4. Adding BaseUrl in the config file
- 5. Defining “ book ” in package.json
- 6. 3rd Party Servers
- 7. Control State Programmatically
- 8. Avoid Single Assertions
- 9. Use Commands to Reuse Code
- 10. Write Open and Descriptive Test Names
- Is Cypress redefine Test Automation?
- Why Run Cypress Tests with BrowserStack Automate
Cypress Best Practices for Test Automation
is a cutting-edge front-end testing tool plan for the modern web. You could easily claim that Cypress solves the major issues that QA engineers and developers have while testing modern applications.
is topic that is frequently counterpoint, however, Cypress is basically and architecturally distinct from Selenium. Cypress is not open to the same limit that utilise to Selenium. As a consequence, you can fabricate tests more quickly, well, and correctly.
This article will discuss some of the good praxis for Cypress test mechanization.
What is Cypress?
is a modern tool designed specifically for the needs of today ’ s web covering. It addresses common challenges that developers and QA team face, such as test reliability, debugging complexity, and slow test execution.
With Cypress, you can perform,,, UI Coverage, and more.
Cypress go direct in the browser, giving real-time feedback and brainstorm to help optimise your trial suite and enhance the overall caliber of your applications.
10 Cypress Best Practices you Need to Know
Here are 10 good pattern that you need to know for Cypress Test mechanisation:
1. Use data Attributes When Selecting Elements
One of the most important best pattern you can assume when creating your is indite selectors completely independent of your CSS or JavaScript. In order to prevent your test suite from be broken by a simple CSS or JavaScript update, you should manufacture selectors that may be explicitly target for testing.
Utilising impost data attributes is the best choice in this case:
// ✅ Do cy.get (' [data-cy= '' link ''] '); cy.get (' [data-test-id= '' link ''] '); // ❌ Don't cy.get ('button '); // Too generic cy.get ('.button '); // Coupled with CSS cy.get (' # button '); // Coupled with JS cy.get (' [type= '' submit ''] '); // Coupled with HTMLThese explicitly state what they are intended to accomplish, and you will be mindful that if you alter them, your test cases will also need to be updated.
It is difficult to select an element using id and class because these attributes are largely used for behaviour and styling, which entail they are constantly subject to change. It & # 8217; s likely a bad idea to do this if you don & # 8217; t want the tests that arrive out of it to be brittle.
Use data-cy ordata-testidinstead wherever possible. Why? They are more reliable because they are created purely for testing and are therefore independent of the behaviour or styling.
Let & # 8217; s say, for instance, that we experience an input constituent:
& lt; input type= '' text '' name= '' name '' / & gt;
To target this element for testing, usedata-testidinstead than id or form:
// Do n't ❌ cy.get (`` # main '') .something (); cy.get (`` .input-box '') .something (); // Do ☑️ cy.get (`` [data-testid=name] '') .something ();
2. Independent it () block
In it () block, we indite the exam instance script. In a spec file, we include several it () block inside the & # 8220; describe & # 8221; block. In this scenario, it is essential that we follow the coding principle that no two it () blocks of codification should depend on one another.
This approach of coding was selected because, when we run a specification file with many it () blocks (for instance, 10 trial cases) if one of them fails, the other it () blocks won & # 8217; t fail either because there is no colony between them.
Also Read:
Using dynamic wait
Some developers write code for any page activity, such as see a URL, preserve, updating, or deleting action, and so waiting for the API to be fighting and return results using thecy.wait (timeout) command.
cy.visit ('/ ') cy.wait (5000) // & lt; -- - this is unnecessaryThe script will wait for five seconds when the aforementioned code is executed, even when the page load in just two or three mo.
Using the static postponement biddingcy.wait (timeout)while writing code in these position is not recommended.
Pro tip: Tools like SUSA can handle this autonomously — upload your app and get results without writing a single test script.
A better fix is to use cy.intercept () while indite dynamic wait code.
cy.intercept ('POST ', ' * * /login ') .as ('login '); cy.visit (`` / '') cy.wait (' @ login ')In the code above, we utilize cy.wait () to hold off on utilize the specific API & # 8220; login. & # 8221; The next piece of code commence to run once we receive the API & # 8217; s result. The main benefit of evolve dynamical code is that it hotfoot up the hand execution and reduces waiting time.
3. Cypress basics: before (), beforeEach (), after () and afterEach ()
Consider that each of the 10 tryout cases in our specification file needs to begin with a few lines of code that are applicable to all of them. In this case, start each it () block with the same repetitive lines of code is not a smart thought.
The answer is to write the code in the beforeEach () hook.
The beforeEach () hookwill automatically fulfil whatever code it contains before each test instance is executed.
In a similar way, theafterEach () come-onmay be used to compose common code that will execute following the windup of each and every test cause. Additionally, we can use the before () hook to write a piece of common code that executes before all trial cases in a specification file are executed. Theafter () hookallows us to indite common code that will execute following the execution of all test cases in a spec file.
4. Adding BaseUrl in the config file
The login page is the base URL of the application in the bulk of lawsuit. The login URL must be use as the base URL in all spec file in order to perform logins and other test-related activities. Some programmers use cy.visit () to difficult code the understructure URL in each specification file & # 8217; s before () cube, as see in the example below:
before (() = & gt; {cy.visit (`` https: //demoapp.com '')})This is a bad tactics because when the spec file is executed in the Cypress moon-curser, it will first lade the localhost URL and then recharge the URL we supplied in the cy.visit.
This takes time and look unprofessional. By recruit the base url as exhibit below in the cypress.json file, this issue can be conclude.
cy.visit (`` http: //localhost:3000/login '') Change it to: cy.visit (`` /login '') cypress.json {... '' baseUrl '': `` http: //localhost:3000 '' ...}5. Defining “ scripts ” in package.json
Typically, we use Optical Studio Code & # 8217; s terminal to execute Cypress commands. To open the Cypress runner, for instance, we & # 8217; ll use the & # 8220; cypress open & # 8221; command. & # 8220; npm run cypress exposed & # 8221; is the terminal command to use. It is urge to include this & # 8220; cypress open & # 8221; dictation in the package.json file & # 8217; s & # 8220; scripts & # 8221; JSON section.
& # 8220; npm run cy: open & # 8221;is the comparable dictation we type in the depot. The & # 8220; scripts & # 8221; JSON allows us to define all the command we use to run in the terminal together with a user-defined name.
The main reward of creating in this method is that, when we need to run lengthy bidding in the terminus, we may define the command in & # 8220; scripts & # 8221; JSON and use the user-defined gens.
6. 3rd Party Servers
It & # 8217; s possible for your covering to have an encroachment on another application developed by a 3rd party. While not often come, these circumstances are nevertheless conceivable. Consider incorporate your app with GitHub so that user can edit data inside of GitHub using the app.
You can use cy.request () to programmatically convey with GitHub & # 8217; s APIs after your tryout has finish running sooner than attempting to cy.visit () GitHub. This eliminates the need to ever interact with another coating & # 8217; s user interface.
7. Control State Programmatically
In order to essay under the appropriate conditions, try to set the state of your application programmatically whenever you can rather than through the UI. As a result, the UI will no longer be dependent on your state.
You will also notice an improvement in performance because the programmatic state setting is quicker than using the UI of your coating.
// ✅ Do cy.request ('POST ', '/login ', {email: 'test @ email.com ', pass: 'testPass'}); // ❌ Don't cy.get (' [data-cy= '' e-mail ''] ') .type ('test @ email.com '); cy.get (' [data-cy= '' passing ''] ') .type ('test @ email.com '); cy.get (' [data-cy= '' submit ''] ') .click ();Instead of using the UI to do the like task, as find in the code sample above, we can utilize cy.request to communicate straight with an API to log a exploiter in. This likewise holds true for other activeness, like adding test data to your application to put it in the proper state.
Learn More:
8. Avoid Single Assertions
Avoid using individual assertion. While single asseveration may work well for unit testing, we are writing E2E trial hither. You will be capable to identify the specific statement that neglect even if you don & # 8217; t divide your up into multiple tryout phases.
// ✅ Do it ('Should have an outside link pointing to the right domain ', () = & gt; {cy.get ('.link ') .should ('have.length ', 1) .find (' a ') .should ('contain ', 'wtips.dev '); .and ('have.attr ', 'target ', '_blank ');}); // ❌ Don't it ('Should have a linkup ', () = & gt; {cy.get ('.link ') .should ('have.length ', 1) .find (' a ');}); it ('Should hold the right textbook ', () = & gt; {cy.get ('.link ') .find (' a ') .should ('contain ', 'wtips.dev ');}); it ('Should be external ', () = & gt; {cy.get ('.link ') .find (' a ') .should ('have.attr ', 'target ', '_blank ');});The nearly substantial piece is that Cypress runs lifecycle events between your examination that reset your province. This ask more processing than simply adding assertions to one test. As a result, indite a single affirmation may hinder the effectiveness of your test suite.
9. Use Commands to Reuse Code
To make tests more maintainable and cut redundancy, leverage Cypress require for recyclable codification. Custom command permit you to encapsulate repetitive action (like logging in or filling out forms) in a single role that can be reused across multiple test cases.
This ameliorate trial readability and simplifies updates—changing the bid in one property will apply update everywhere it ’ s used. Define usance commands in Cypress ’ scommands.jsfile to engineer and streamline your examination suite.
10. Write Clear and Descriptive Test Names
Clear, descriptive test names make see what each tryout extend easygoing without plunge into the codification. Efficacious trial names should summarize the specific activity be tested and the expected consequence, like ‘should display erroneousness message for invalid login’.
This approach helps with debugging, improves communication within the team, and makes test report more useful for tracking failure. Remember to continue trial name consistent and concise for easier maintenance and legibility.
Is Cypress redefining Test Automation?
Yes, Cypress has introduced features that simplify and enhance test mechanisation.
Below is a inclination of the suppose characteristic:
- Quick Setup and Usage: Cypress is easygoing to install and start, countenance users to quickly set up automated test for critical functionalities. It even provides demonstration to guide you through using each feature.
- Time Travel Debugging: Cypress seizure snapshots during tests, enabling you to “ clip traveling ” backwards to see the exact state of the covering at each command—a unique feature in trial mechanization.
- : Cypress offers clear erroneousness message, pinned snapshot to present before-and-after states, and full access to browser developer puppet, making debugging faster.
- Bundled JavaScript Tools: Cypress includes popular tools like jQuery, Moment, Sinon, Lodash, Mocha, and Chai for seamless testing within the JavaScript ecosystem.
- Automatic Retry-ability: Cypress waits for commands and assertions to pass without hardcoded waits, adjust dynamically to the laden speed of DOM elements, making it ideal for testing dynamic apps.
- Visibility-Driven Interactions: Cypress just interact with visible component and automatically waits for spiritedness and request to complete, reducing craziness in tests.
- HTTP Request Control: With cy.intercept (), you can tap and wait for HTTP requests, make tests more stable and controlled.
- Effective Element Selection: Cypress ’ scy.get()locates elements more quickly than Selenium, as it doesn ’ t rely on explicit waits, allowing both front-end and unit testing in one tool.
- Spies, Stubs, and Clocks: Cypress provides control over function behaviors, waiter response, and timer, afford you unit testing-like control in end-to-end tests.
Why Run Cypress Tests with BrowserStack Automate
Running Cypress analogue tests on offers several benefits:
- Seamless Integration: Cypress doesn ’ t support parallel testing locally, but BrowserStack Automate integrates smoothly, enabling efficient parallel test execution.
- : Access to a wide range of existent devices and environs ascertain tests reflect actual exploiter weather.
- Enhanced Security: Real gimmick clouds provide secure, sequestrate testing environs, reduce risks of data rupture.
- Broad Browser and OS Coverage: Helps place compatibility issues across different browser and operating system, ameliorate user experience.
- Performance Insights: Real devices deliver accurate performance datum to optimize app responsiveness.
- Scalability and Accessibility: Enables scalable quiz for distributed teams.
- Integration: Easily integrates into CI/CD pipelines for uninterrupted examination and quick subject detection.
- Cost-Effectiveness: While the initial toll is high, it salvage long-term expenses by reducing the need for fixes and support.
Conclusion
Leverage the various advantages of Cypress to run parallel tests effortlessly. Use BrowserStack ’ s real browser to ensure that all tests return 100 % accurate termination, even when execute multiple tests simultaneously.
Don ’ t boundary your Cypress grouping examination to the various inadequacies of emulators and simulators; exclusively rely on the real deal to create customer-ready, meticulously optimized web applications.
On This Page
- What is Cypress?
- 10 Cypress Best Practices you Need to Know
- 1. Use data Attributes When Selecting Elements
- 2. Independent it () cube
- 3. Cypress basics: before (), beforeEach (), after () and afterEach ()
- 4. Adding BaseUrl in the config file
- 5. Defining “ hand ” in package.json
- 6. 3rd Party Servers
- 7. Control State Programmatically
- 8. Avoid Single Assertions
- 9. Use Commands to Reuse Code
- 10. Write Open and Descriptive Test Names
- Is Cypress redefining Test Automation?
- Why Run Cypress Tests with BrowserStack Automate
# Ask-and-Contributeabout this theme with our Discord community.
Related Guides
Automate This With SUSA
Upload your APK or URL. SUSA explores like 10 real users — finds bugs, accessibility violations, and security issues. No scripts needed.
Try SUSA FreeTest Your App Autonomously
Upload your APK or URL. SUSA explores like 10 real users — finds bugs, accessibility violations, and security issues. No scripts.
Try SUSA Free