question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Replacing Dependency Injection with NodeJS modules in tests

See original GitHub issue

First breaking change announced! 🤩 🍰

Motivation

Currently to load support objects (I, page objects, etc) into tests we use dependency injection into a function. An object is loaded by its name declared in include section of config file. So every test needs at least I parameter of a function for a test:

Scenario('sample test', (I, loginPage, adminPage) => {
  I.amOnPage('/');
  // ...
});

However, the biggest limitation in DI that it works only for tests. Inside PageObjects and StepDefinitions (for BDD testing) we can’t rely on DI (or use absolutely a different API).

Solution

It appears that all support objects (except I) can be loaded by simply requiring modules:

const I = actor(); // or require('codeceptjs).actor() if not globally installed
const loginPage = require('./loginPage');

Scenario('sample test', () => {
  I.amOnPage();
});

Pros

By replacing DI loaded support objects with modules we:

  • simplify configuration (included section in config is not needed)
  • make CodeceptJS friendlier to wider JS community
  • unifying a way to load support objects
  • allows to load objects from other Node modules, paths, globally, etc.

Cons

Alternative Solution

An alternative with a shorter migration path is to provide global function inject or support, which will load all objects into test by their names. Unlike current approach, objects are loaded per file basis. And this can be used everywhere: in tests, in page objects, in step definitions:

const { I, loginPage, userPage } = inject();

Scenario('sample test', () => {
  I.amOnPage();
});

Pros

  • simpler code, shorter migration
  • unified approach
  • configuration is not changed
  • does not use on relative paths to load objects

Cons

  • requires an additional global object (inject)
  • magically loading modules
  • higher learning curve for CodeceptJS

I really need a feedback to continue! Vote for solutions, propose an alternative. CodeceptJS 2.0 needs your input!

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:1
  • Comments:6 (2 by maintainers)

github_iconTop GitHub Comments

2reactions
APshenkincommented, Sep 15, 2018

@DavertMik Still love DI in tests. This reduce boilerplates in code (require several page objects in each tests file). And DI also give you consistency for page objects naming in all tests (you will not call the same page object different in different test files)

allows to load objects from other Node modules, paths, globally, etc.

Also this option is availible right now. You can load objects from node modules ans paths. (BTW, any global requirement is a PAIN 😁)

we can’t rely on DI (or use absolutely a different API).

agree but looks like not a problem. page objects are not a “frontend” of tests. And you can use any mechanism to load them in other page objects.

There can be issues regarding async functions inside page objects. Right now we inject recorder.saveFirstAsyncError into every async function.

Also this looks critical

So in my opinion, if it possible to support require and DI, it’s better to support both

And no breaking changes at all 😉

0reactions
DawidTabakcommented, Oct 8, 2018

@DavertMik Is there a separate issue for test migration script? I’ve created an separate repository implementing basic migration using jscodeshift. It’s still in a POC state and has been tested using npm link (windows 10). https://github.com/DawidTabak/codeceptjs-migrate20-include

Read more comments on GitHub >

github_iconTop Results From Across the Web

Replacing Dependency Injection with NodeJS modules in tests
First breaking change announced! Motivation Currently to load support objects (I, page objects, etc) into tests we use dependency ...
Read more >
Simplify your Unit Tests with Dependency Injection for ... - Bitovi
Use Dependency Injection to simplify your unit tests with the JavaScript module format you're already using and without changing your code.
Read more >
JavaScript dependency injection in Node.js – introduction
Dependency injection in JavaScript is a well-known technique, which can make it much easier to produce independent and scalable modules.
Read more >
Dependency injection with Node.js, Express.js and TypeScript
Dependency injection decouples your code which makes your application more adaptable to changing requirements. It also has the added benefit of ...
Read more >
How to mock a dependency in a Node.js, and why you should ...
This right way to mock is DI!​​ DI is cool and very handy way to replace dependencies, and it will help you in...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found