8

I have an app that runs in different modes (think of it as running for different platforms as well as using different protocols), one of which has a long loading period every time a page is opened. There are some other minor changes, but all of those could just be taken care of using wdio's setting variables.

Currently I have one test file (with a describe) for each section of the app. Which would be fine if one of the configurations being tested didn't have such a long wait time. Anyway, I've decided to deal with this test case, to handle it all in one file, which will all be on the same page.

Anyway, instead of copying and pasting all the tests I had previously to this one large file I was wondering if I could somehow reuse them, as if they were functions.

As it is right now I did just wrap things in functions, so for example:

// test1.js
module.exports = function test1 () {
  describe('Test1', function () {
    var settings = {}

    before(function () {
     // do something
    })

    it('do something', function () {
      assert.ok(true)
    })
    it('do something else', function () {
          assert.ok(true)
    })
  })
}

In another file we run every single function we created:

test1 = require('./test1')
test2 = require('./test2')
...
test10 = require('./test10')
describe('Main Test', function () {
  test1()
  test2()
  ...
  test10()
}

This would have solved my DRY problem, if I could somehow select which test functions to run upon my command using

wdio wdio/wdio.conf.js --specs wdio/test/spects/browser/test1.js

Which obviously will not work.

Basically I want a solution to be able to reuse my tests (the describe blocks). Is what I was doing the right path? If not, how should it be done?

theJuls
  • 6,788
  • 14
  • 73
  • 160
  • Quite unclear what you mean by"one file on the same page". And the code does not show any code to share. – oligofren Jul 29 '17 at 07:05

2 Answers2

11

So I have figured out the best way to go about this after I found some documentation about it here.

I will just do as I previously described, however instead of shoving all those functions in the same file, I'll keep them in their own files. There still may be a better solution out there, but it is still an improvement from copying and pasting all test cases for the different modes of running my app.

theJuls
  • 6,788
  • 14
  • 73
  • 160
  • There are a lot of problems with that example. It doesn't for example, should how to make the function parameterized with, say, a user ID. Instead, it relies on singleton state. – user48956 Nov 16 '22 at 19:31
1

Just programmatically create different describe blocks. Wrap the describe block in a function with all the parameters that change (including the name of the block) and simply invoke the function to create the variations.

I made a small repo to show this in practice: https://github.com/fatso83/forum-support-code/commit/cb2bc10b1d8bdae31e8f0a8c4e724c70583a5e11

oligofren
  • 20,744
  • 16
  • 93
  • 180
  • This doesn't work that well when you need variables to be visible across both the requiring file and the required file. For example, to make a shared context "when user is signed in", and have the user available within the context. At least, I couldn't get such a thing to work. – Pistos Mar 28 '19 at 18:22
  • You are mixing things. Different files doesn't change the concept. If you can do it using a closure, you can of course do it using different files (that's just code organization). You share the user context by sending it into the function creating the describe blocks. – oligofren Mar 28 '19 at 18:43
  • @Pistos I can create an example on Runkit if you need an example of dynamically creating test suites. – oligofren Mar 28 '19 at 18:44
  • The issue I ran into was that the `user` instance that my shared code introduced (via, say, `let`) needed to be made available to the inner block. e.g. `whenUserSignedIn( function(user) { describe('more tests here')..... } )` Not only that, but the supertest agent also needed to be shared between the `whenUserSignedIn` code and the file that was `require`-ing the shared code. In particular, the `agent` was to be instantiated (in a `beforeEach`, no less) in the `require`-ing code, but used in the shared code. It was all just messy and frustrating, and a far cry from the ease of, say, rspec. – Pistos Mar 28 '19 at 21:42
  • Couldn't you just export the function in the shared code and pass in the variables to that function when requiring it? I don't see how the separate file makes this harder, but I'll look into it . Has used this approach many times – oligofren Mar 29 '19 at 06:55
  • @Pistos I made a small repo to show this. Does this make it clearer? https://github.com/fatso83/forum-support-code/commit/cb2bc10b1d8bdae31e8f0a8c4e724c70583a5e11 – oligofren Apr 03 '19 at 20:11
  • Thank you for your persistence. I meant to get back to you, but my project has moved on to other things, so my issue is temporarily on the backburner. I can get you a more detailed example, but roughly I need something like this: https://gist.github.com/Pistos/cb5b582d848376e1869395b89f2ede15 . I can do something like that already in the simple case, but there are complications that are impeding me. – Pistos Apr 04 '19 at 23:12