News for hackers. Stuff that matters.
Re:Cypress: Fast, easy, and reliable testing for anything th... by BurningFrog on Thursday December 10, 2020 @10:54PM (#25382099)
I spent a few weeks with it, and it was very frustrating.

The programming model is very odd. I found it next to impossible to share any code between tests, and most of the programming skills I've learned over the decades didn't seem to apply.

It is vastly superior to anything else we've seen in stability and polish. If I only could write reasonable code for it, things would be great...

Re:Cypress: Fast, easy, and reliable testing for anything th... by Shacklz on Friday December 11, 2020 @03:38AM (#25383662)
I found their idea about defining commands very odd, but when we ignored these entirely and just went with the good old page pattern, the tests became very tame again. All the cypress-internals are done in small methods within page-objects, the tests contain only the abstract page-object-methods.

But yes, when we tried to run with the patterns they advertise, the tests became indeed hard to write and read; maybe we did it all wrong but it's at least consistent with the experience expressed by you and others in the thread here.

Re:Cypress: Fast, easy, and reliable testing for anything th... by Macha on Friday December 11, 2020 @09:07AM (#25385889)
The one slight gotcha is if you go for the page object pattern the intuition is that each page object holds a reference to the cypress element that formed it so you can do new LoginForm(cy.get('#loginForm')) or similar which is a mistake because of the way cypress chaining works - it will result in only being able to use a single method once on the page object. Instead you need to query fresh again each time.

Which is fine when the page object is a login form, but a bit more comfortable complicated when it's notification 5 or something.

Re:Cypress: Fast, easy, and reliable testing for anything th... by veidr on Friday December 11, 2020 @12:08PM (#25387993)
Good point, I'd gotten used to that and forgotten how it is kind of counterintuitive at first. Our base test helper object does this:

  get root() {
    // It is important here to run cy.get() 
    // each time this property is accessed. 
    // Lots of methods of this class chain 
    // off of `this.root` so it needs to be 
    // re-evaluated every time.

    return cy.get(rootComponentCss);
  }

  find(selector: string, options?: any) {
    return this.root.find(selector, options);
  }

...so that component-specific test helper objects (subclasses) can just do something like:

  get sendMissileAlertButton() {
    this.root.find('.x-hawaii-missile-incoming');
  }
That way, it looks up the target element every time it is used in a test.

And in tests, you can just do:

    tester.root.find('select.foo').select('hoge');
    tester.sendMissileAlertButton.click();
EDIT: fixed code example, sorry! ;-)
Re:Cypress: Fast, easy, and reliable testing for anything th... by jwikstrom on Friday December 11, 2020 @02:14AM (#25383237)
I think its great! You have to overcome the async approach, but once you understand that writing tests are SO much faster and reliable!
Re:Cypress: Fast, easy, and reliable testing for anything th... by inglor on Friday December 11, 2020 @04:08AM (#25383778)
I've compared a few thousand tests in each testing library from real companies and I've found Cypress to be with "as many defects as Selenium in real projects".

Most of the other open source tools (not to mention enterprise tools like Testim.io where I work) support the things that make Cypress "fast" like mocking network requests or automatically waiting for elements. I wrote an article about this somewhere I can dig it if you want.

If you have data showing differently I'd love to see it.

Re:Cypress: Fast, easy, and reliable testing for anything th... by vitorbaptistaa on Friday December 11, 2020 @08:35AM (#25385510)
If you can find it, I'd be curious to read about the article you mentioned.
Re:Cypress: Fast, easy, and reliable testing for anything th... by dvlsg on Friday December 11, 2020 @01:04AM (#25382826)
Did you ever need to mix cypress tests with anything else? Say for example I wanted to have cypress click through a frontend, and then make a separate backend call to verify something happened in the same test run. Is there a clean way to do that in a cypress context, or is playwright / puppeteer going to be a better fit?
Re:Cypress: Fast, easy, and reliable testing for anything th... by adventureadmin on Friday December 11, 2020 @02:30AM (#25383309)
What's your backend written in? I'm in a similar position where work is pushing cypress, but there is no library for cypress in our backend language, there is for playwright. I want to do something in the frontend, and check the backend, so it would be nice to use our existing backend language for both so we have access to our internal library. I was told we could write a bash script and have cypress exec. Of course we can do a script in any language, but suddenly I'm seeing a bash QA library emerging at my work. Does that sound absurd to anyone else?
Re:Cypress: Fast, easy, and reliable testing for anything th... by Shacklz on Friday December 11, 2020 @04:53AM (#25384016)
What do you mean with "check the backend"? You can e.g. do assertions on HTTP-responses coming from the backend - is this what you head in mind?

If you want to test the backend on its own, I personally would recommend using a different framework than cypress (or a different framework than the one being used for frontend e2e testing in general). Otherwise you risk that people conflate these two things and start "testing the backend" in e2e-tests for the frontend, which are super slow.

Re:Cypress: Fast, easy, and reliable testing for anything th... by dvlsg on Friday December 11, 2020 @11:14AM (#25387364)
Yeah, specifically that interfacing with the ui causes some side effects we would expect to happen (web hooks sent, reports generated, etc). I definitely wouldn't want to write all of our tests that way, because that sounds like a nightmare to maintain and run, but was considering a handful for covering a few major features. We do already have a very extensive backend integration test suite (http / rest interactions) that doesn't do anything with UIs, though.

Cypress is a recent addition for us, so this is more a curiousity than anything else. I've done similar fully e2e / functional tests with puppeteer in the past.

Re:Cypress: Fast, easy, and reliable testing for anything th... by dvlsg on Friday December 11, 2020 @11:08AM (#25387286)
Our backend is in node / typescript, so it's theoretically possible to mix the two. I would be able to test what I need using REST APIs, though, so in theory the backend language doesn't really matter for me.

I haven't had much time to try anything yet, but cypress's override of promises and async / await makes me think it'll be a pain to try adding non-cypress-specific checks to a cypress test.

Re:Cypress: Fast, easy, and reliable testing for anything th... by sumedh on Sunday December 13, 2020 @07:00AM (#25405968)
Ideally you should not combine Cypress Frontend end to end tests with backend testing.

You use Cypress to do something on the frontend, which triggers something on the backend and ideally that change is reflected on the frontend, you test that frontend change using Cypress.

For backend testing just directly call the backend API's and then check the database directly.

Re:Cypress: Fast, easy, and reliable testing for anything th... by monkeynotes on Friday December 11, 2020 @08:47AM (#25385629)
There is a difference between integration testing (Cypress UI click through UI) and backend unit testing.

We run integration tests with Cypress and then rspec or some other Rails testing platform for the backend.

Cypress uses fixtures so ideally you would not let it hit a backend API unless you don't care about reproducibility of the response. For example a PUT will augment the data on the backend so when you run the test again the backend data will probably give you a different response to assert and fail your expected.

Re:Cypress: Fast, easy, and reliable testing for anything th... by wdb on Friday December 11, 2020 @05:41AM (#25384297)
Due to the limitations of Cypress you end up using them both.

Cypress for the simple tests, and for the more complex case, e.g. opening tabs, testing your SSO login paths, I frame widgets, you end up using Playwright. I spend quite a lot of time to even fork Cypress to add support for testing WebKit browsers. Probably was quicker to write a Cypress kind of solution for Puppeteer/Playwright

Re:Cypress: Fast, easy, and reliable testing for anything th... by satyrnein on Friday December 11, 2020 @05:55PM (#25392684)
We have Cypress tests that call our database directly and get information out, call 3rd party APIs to get information back, and call our APIs we've specifically created ourselves to help Cypress tests. It's pretty flexible; I'm just not sure how much this flexibility might bite us in the future.
Re:Cypress: Fast, easy, and reliable testing for anything th... by Can_Not on Friday December 11, 2020 @11:26PM (#25395535)
One thing I didn't see mentioned is to just have some extra routes in /tests/* that are only enabled for tests to call or return data from arbitrary back-end code.
Re:Cypress: Fast, easy, and reliable testing for anything th... by wilsonrocks on Friday December 11, 2020 @01:12AM (#25382867)
cy.exec() lets you run general system commands iirc. Istr seeding a database with it before running tests, I think if that command fails with Nonzero, the test would fail.
Re:Cypress: Fast, easy, and reliable testing for anything th... by Mavvie on Friday December 11, 2020 @12:04AM (#25382500)
What made it hard to reuse code? You can just import/export stuff like normal, unless you mean it was hard to find any logic that could be usefully extracted into a helper?
Re:Cypress: Fast, easy, and reliable testing for anything th... by BurningFrog on Friday December 11, 2020 @12:40AM (#25382706)
We have a lot of data in UI tables, so I wanted to write code that extracted the cell values to a ROWSxCOLUMNS matrix, that I could reuse in each test.

And... I just couldn't figure out a way!

Re:Cypress: Fast, easy, and reliable testing for anything th... by wilsonrocks on Friday December 11, 2020 @01:14AM (#25382882)
Did you try custom commands? I have some for more basic stuff like 'get data-value attribute for the element with data-name attribute of x' which I can use in any test.

That said, I find checking for specific values in the page against other page values to be really difficult so if you're doing that with the table... good luck!

Re:Cypress: Fast, easy, and reliable testing for anything th... by 867-5309 on Friday December 11, 2020 @01:00AM (#25382798)
if that functionality isn't already present in the UI, e.g. by selecting a filter or exporting, then perhaps it belongs in the domain of a scraper rather than a testing tool
Re:Cypress: Fast, easy, and reliable testing for anything th... by monkeynotes on Friday December 11, 2020 @08:42AM (#25385590)
Reusable code is somewhat achievable if you use helpers (commands). Example:

``` Cypress.Commands.add('yourHelperName'), () => { //your code } ```

Re:Cypress: Fast, easy, and reliable testing for anything th... by veidr on Friday December 11, 2020 @11:04AM (#25387243)
I love Cypress overall, but wouldn't advocate using Cypress commands unless you are doing something weird.

Their examples show using Cypress commands for pedestrian things like "log in to app" but there is no need to get all Cypress-specific for things like that.

Instead, we typically write "test helper" objects for that, which are conceptually similar to the Page Objects pattern from the Selenium era. So like:

    class GroupUiTester {
        get groupChooser() {
            return cy.get('#group-chooser-button');
        }
    }
Then, in your test, you can just be like:

    tester.groupChooser.click();
That is kind of simplified, but even that would be useful if you had dozens of tests interacting with that group chooser element. (Especially since, unlike string-based "cy.get('.some-class.whatever')" it will all auto-complete in any decent editor.)

An example of "doing something weird" where we do use Cypress.Commands is like:

    Cypress.Commands.add('disableDefaultLocalStorageClearing', () => {
        Cypress['LocalStorage'].clear =
            SUBSTITUTE_CYPRESS_CLEAR_LOCAL_STORAGE_FUNCTION;
    });
We do that because the local storage clearing breaks a third party lib we use for a few tests. But that is something you can't just do with the regular Cypress/DOM API, so it is a good candidate for using Cypress "commands".
Re:Cypress: Fast, easy, and reliable testing for anything th... by foolfoolz on Friday December 11, 2020 @09:31AM (#25386191)
we have extensive Page Objects which let us re use code everywhere. i’m not a huge fan of cypress commands because they pollute a public prototype and i don’t like modifiying those
Re:Cypress: Fast, easy, and reliable testing for anything th... by veidr on Friday December 11, 2020 @11:12AM (#25387336)
Ditto. It is really easy to write re-usable code for Cypress tests in plain TypeScript/JavaScript, and just directly import the file.

    x.usernameField.type('Joe User');
    x.passwordField.type('$ecureBR0');
    x.enterWrongCaptcha();
    cy.get('.err-captcha-fail').should('be.visible');
Basically, I think all the code to locate UI elements and perform common interactions with them should be in re-usable utility code, so that the actual tests can focus on just testing what they test.

I don't think the Cypress docs probably do a great job emphasizing how easy this is (especially since they go out of their way to de-emphasize the 'page objects' pattern, but without offering much in the way of a replacement).

Re:Cypress: Fast, easy, and reliable testing for anything th... by Macha on Friday December 11, 2020 @02:14PM (#25389497)
Yes, I'll echo my disagreement with the Cypress advice against the page object pattern - the advantage was always that the logic to get the element could be updated in a single place, and that applies as much whether that code is 3-5 lines of webdriver code or one line of cypress code.
Re:Cypress: Fast, easy, and reliable testing for anything th... by foolfoolz on Friday December 11, 2020 @11:31AM (#25387534)
100% this is the model we follow. no dom in tests helps a lot. the cypress docs don’t make any sense here
Re:Cypress: Fast, easy, and reliable testing for anything th... by veidr on Friday December 11, 2020 @11:49AM (#25387770)
Yeah, "no DOM in tests" is actually a pretty good mantra.

Code that is just inspecting the DOM to find elements, or to do stuff to them that is just working up to the state where you can actually test something, should be in some shared object/library, but that is as easy as:

    import { Whatever } from '/foo/bar';
Having that kind of code outside of the test probably makes the introductory "test hello world" example more complicated, but I think it's definitely a good practice in the real world, and isn't documented well.
Re:Cypress: Fast, easy, and reliable testing for anything th... by strunz on Thursday December 10, 2020 @11:21PM (#25382250)
Last time I checked you couldn't even organize tests in different folders, I wonder if they finally fixed that. I always find it odd using test frameworks developed by a for profit company. They pick and choose what code to merge and bugs to fix based on their own priority, not what's best for the users.
Re:Cypress: Fast, easy, and reliable testing for anything th... by exdsq on Friday December 11, 2020 @02:00AM (#25383167)
I found this when I used Cypress at a contract last month - ended up just using a Makefile `make test` to run every suite.
Re:Cypress: Fast, easy, and reliable testing for anything th... by fn1 on Friday December 11, 2020 @01:50AM (#25383115)
Could you write code in a better language like kotlin and then transpile it to javascript?
Re:Cypress: Fast, easy, and reliable testing for anything th... by jpsimons on Thursday December 10, 2020 @11:33PM (#25382328)
It's like Obamacare -- deeply flawed but hey at least they're trying to do something.