Cypress Assertion helps us to assert a particular Assertions are validation steps that ensures whether the expected result is equal to the actual result. In test automation, we assert a statement to verify that the test is generating the expected result. If the assertion fails, then the test case fails ensuring that there is a bug. In this article, we will discuss about Cypress Assertion with Handson implementation and examples.
Table of Content
- What is Cypress Assertion?
- Cypress Assert Text
- Cypress Common Assertion
- Cypress Retry Assertion
- Cypress Assertion Examples
- Implicit Assertion in Cypress
- Explicit Assertion in Cypress
- Negative Cypress Assertion
- Cypress Custom Assertion Message
- Cypress Assertion Best Practices
What is Cypress Assertion?
Cypress uses and wraps Chai assertion library and extensions like Sinon and JQuery. Cypress automatically waits and retries until the assertion is resolved. Assertions can be used to describe how the application should look like. We can use Cypress assertions with combination of waits, retry, block until it reaches the desired state.
Cypress Assert Text
In general English, we would describe an assertion something like, I would expect the button to have login text. The same assertion can be written in Cypress as
cy.get('button').should('have.value', 'login')
The above assertion will pass if the button has ‘login’ value.
Cypress Common Assertions
There are a set of common Cypress assertion that we use in our test cases. We will be using them with .should()
. Let us look into the use case and examples.
Some of the common Cypress assertion are listed below
- Length
- Value
- Text Context
- Class
- Existence
- CSS
- Visibility
- State
- Disabled Property
Cypress Length Assertion
length()
will check if the particular element has length
cy.get('dropdown').should('have.length', 5)
Cypress Value Assertion
The Cypress value will assert if the particular element has the expected value
cy.get('textfield').should('have.value', 'first name')
Cypress Text Context Assertion
Text context will assert if the element has the particular text
cy.get('#user-name').should('have.text', 'John Doe')
Cypress Class Assertion
Asserts whether the class is present or the particular element should have the class
cy.get('form').find('input').should('have.class', 'disabled')
Cypress Existence Assertion
Existence command checks whether the particular element is present or exist in the DOM or not
cy.get('#button').should('exist')
Cypress CSS Assertion
CSS Assertion checks whether the particular elements has a particular property
cy.get('.completed').should('have.css', 'text-decoration', 'line-through')
Cypress Visibility Assertion
Cypress Visibility Assertion asserts whether the DOM element is visible in the UI
cy.get('#form-submit').should('be.visible')
Cypress State Assertion
Asserts the state of the DOM element
cy.get(':radio').should('be.checked')
Cypress Disabled Property Assertion
Cypress Disabled property assertion asserts whether the element is disabled
cy.get('#example-input').should('be.disabled')
Cypress Retry Assertion
A single command followed with an assertion will execute in order. Initially, the command executes and then the assertion will get executed. A single command followed by multiple assertions will also execute in order – first and second assertion respectively. So when the first assertion passes, the first and the second assertion will be executed along with the commands again.
For example, the below command contains both .should()
and .and()
assertion commands, where .and()
is otherwise known as .should()
cy.get('.todo-list li') // command .should('have.length', 2) // assertion .and(($li) => { // 2 more assertions expect($li.get(0).textContent, 'first item').to.equal('todo A') expect($li.get(1).textContent, 'second item').to.equal('todo B') })
Cypress Assertion Examples
In this section, we will discuss on the different types of assertions in Cypress such as
- Implicit Assertion
- Explicit Assertion
We will look into detail on both the types with examples
Implicit Assertion in Cypress
In implicit assertion, we use .should()
or .and()
commands. These assertion commands apply to the currently yielded subject in the chain of commands. They are dependant on the previously yielded subject.
We will look into an example on how to use .should()
or .and()
commands
cy.get('button').should('have.class', 'enabled')
With .and()
which is an alias of .should()
,we can chain multiple assertions. These commands are more readable.
cy.get('#title') .should('have.class', 'active') .and('have.attr', 'href', '/post')
The above example is chained with .should()
stating it should have the class “active”, followed by .and()
is executed against the same command. This is very helpful when we want to assert multiple commands.
Explicit Assertion in Cypress
Passing explicit subject in the assertions falls under the explicit type of Cypress assertion. Here, we will use expect
and assert
commands as assertion. Explicit assertions are used when we want to use multiple assertions for the same subject. We also use explicit assertion in Cypress when we want to do custom logic prior making the assertion.
We will look into the example for explicit Cypress assertion
expect(true).to.be.true //checks for a boolean expect(object).to.equal(object)
Negative Cypress Assertion
Similar to positive assertions, there are negative assertion in Cypress. We will be using “not” keyword added to the prefix of the assertion statement. Let us see an example of negative assertion
cy.get('#loading').should('not.be.visible')
Negative assertion is recommended only in cases to verify that a particular condition is no longer available after a specific action is performed by the application.
For example, let us consider that a toggle is checked and verify that it has been removed
// at first the item is marked completed cy.contains('li.todo', 'Write tests') .should('have.class', 'completed') .find('.toggle') .click() // the CSS class has been removed cy.contains('li.todo', 'Write tests').should('not.have.class', 'completed')
Cypress Custom Assertion Message
With Cypress, we can provide additional information or custom message for assertions by using a library of matchers. Matchers comprises of small functions that differentiate values and will throw detailed error message. Chai assertion library will help our code look more readable and test failure very useful
const expect = require('chai').expect it('checks a number', () => { const value = 10 const expected = 3 expect(value).to.equal(expected) })
Cypress Assertion Best Practices
We can write multiple assertions in a single block by using a chain of commands. It is not necessary to write single assertion like in unit tests. Many write assertions like below. It is okay to write in that manner, but it increases the line of code and redundancy.
describe('my form', () => { before(() => { cy.visit('/users/new') cy.get('#first').type('ashok') }) it('has validation attribute', () => { cy.get('#first').should('have.attr', 'data-validation', 'required') // asserting whether the #first has required field }) it('has active class', () => { cy.get('#first').should('have.class', 'active') // asserting whether the #first has active class }) it('has formatted first name', () => { cy.get('#first').should('have.value', 'Ashok') // asserting whether the #first has capitalized first letter }) })
As you see above, the same selector and assertion type is getting repeated. Instead, we can chain these commands in one single assertion which performs all the checks in a linear fashion.
describe('my form', () => { before(() => { cy.visit('/users/new') }) it('validates and formats first name', () => { cy.get('#first') .type('ashok') .should('have.attr', 'data-validation', 'required') .and('have.class', 'active') .and('have.value', 'Ashok') }) })
As mentioned above, we can chain the single selector with multiple assertions! This is one of the recommended best practices of writing assertion in Cypress.
To understand about the Page Object Model in Cypress, click here.
Hi…I am Aishwarya Lakshmi, completed my B.Tech and have nearly 2+ years of experience in the testing domain. I am a testing enthusiast and passionate about testing and love to explore new things in my field and share them with my peers. I enjoy writing blogs during my free time in the simplest but effective way. As a tester, I like to have things to perfection, so I wish my readers to have the perfect understanding of the technology. I keep myself updated with the new technologies related to testing and spend time understanding them. I am glad to help students understand the concepts in testing.