https://cypress.io logo
Best Practices: Custom commands assertions & suppl...
# i-need-help
p
Questions: Which is considered more efficient or better in general regarding these two? 1. When you run a custom command to create something, do you run assertions within the command or inside the test case where the command is being used? 2. When you supply test data to supposedly create a new entity (say from a fixture), is it recommended to do that on the test (it) block level or within the custom command used? Example: A command used to create new 'products' & 'customers' etc
Copy code
Cypress.Commands.add('createNewEntity', (entityType, entityData) => {
    // Customize the API endpoint based on the entity type
    let endpoint;
    let modal;

    // Code here to manage endpoint and the create form modal 

    // Intercept the create request
    cy.intercept('POST', env.baseUrlAPI + endpoint).as('createRequest');
  
    // Fill in the form fields based on the entity data
    // cy.get(modal).within(() => {
      Object.entries(entityData).forEach(([labelText, value]) => {
        cy.fillField(modal, labelText, value);
      });
      cy.get('data-testId='create-button').click({ force: true });
   // });
  
    // Close the create modal and wait for the response
    cy.get('.mdi-close').click();
    cy.wait('@createRequest').its('response.status code).should('eq', 200);

    // Verify that the entity was created
    // extra assertions code goes here.
Now for instance I can now call this inside my tests using
Copy code
// to be loaded by data from the customer fixture

// Create a new entity
  cy.createNewEntity('customer', {
      'first name': 'Test',
      'last name': 'Tests',
      'email': 'test001@test.com',
      'phone': '0923823525',
      'location': '32a Test',
      'password': '12345678',
      'confirm password': '12345678',
         });
This works, however, I am not entirely sure if it is recommended, what are your thoughts?
e
For me it entirely depends on whether or not I will need to use that code again in another test. If the answer is yes I throw as much of that as I can into the commands file and set it so it can be used by other tests (args as needed etc), otherwise I will just have everything in the spec file.
e
1. In general I agree with @echoing-tent-95037 where custom commands are primarily beneficial when reused by other tests. If it's a custom command it should always been written in a way such that the consuming test can dynamically customize it as needed with params. I typically don't do a lot of validations in my custom commands because each test case is usually validating different things. That being said, validations such as status code are consistent and seem like a good place to do right after making that call. Test-specific validations should happen in the tests themselves and outside of custom commands. 2. I typically supply the test data at the test level because I want the test to have control over what it's creating. If multiple tests use the same data then I might have some default, set data in the custom command but still allow tests to override as needed. I personally abstract all data creation and API calls into custom commands. I actually take it a step farther and abstract those into their own files, so the custom commands just become more of a wrapper at that point. Just to keep the
commands
file clean since it can get really large over time. Here's an example

https://cdn.discordapp.com/attachments/1097760206483628062/1097929781066076301/image.png

e
Yeah good point @enough-truck-68085 I should have mentioned I do something similar with requests. That gets its own separate file. We got to the point where our commands file was way too big, so separating some of that stuff out made it way easier to navigate and change as needed later.
p
Thanks @echoing-tent-95037 & @enough-truck-68085, this answers my question and is generally quite useful to know.
2 Views