Jest: Jest tests run against local code, not against the bundle

Created on 13 Jul 2017  路  13Comments  路  Source: facebook/jest

Bug: Jest runs code from disk, ignores bundled code with shims

What is the current behavior?

I am using Ignite CLI, so I first filed this issue here: https://github.com/infinitered/ignite/issues/1107
See here for additional details.

The problem is that Jest seems to be running tests against the files on my local disk, rather than those that were packaged in the output bundle.
I noticed this because I have shims that should cause unit tests to fail (I have node-based dependencies that I want to mould into my RN project), but they are succeeding.
The deployed app in the emulator is giving the expected errors.

What is the expected behavior?

The tests should fail, so I can debug and figure out which shims I have to tweak to get the node packages running in RN.

Please provide your exact Jest configuration and mention your Jest, node, yarn/npm version and operating system.

  platform           linux                                                                                                
  arch               x64                                                                                                  
  cpu                4 cores                  Intel(R) Core(TM) i7-4500U CPU @ 1.80GHz  

JavaScript
  node               7.10.1       /usr/local/bin/node  
  npm                4.2.0        /usr/local/bin/npm   
  yarn               0.24.6       /usr/bin/yarn        

React Native
  react-native-cli   2.0.1       
  app rn version     0.45.1      

Ignite
  ignite             2.0.0        /usr/local/bin/ignite  

Android
  java               1.8.0_111    /usr/bin/java  
  android home       -            undefined

Most helpful comment

@cpojer

This is the expected behavior. Jest is supposed to run on source files. On any large codebase, generating a bundle before running tests is too slow, so Jest compiles files just-in-time, which makes it fast.

Is it possible to run tests on bundled code though? I'd like to do this in the final step of my CI so I know the actually code which we will be putting into production is tested, it seems rather flaky otherwise.

All 13 comments

This is the expected behavior. Jest is supposed to run on source files. On any large codebase, generating a bundle before running tests is too slow, so Jest compiles files just-in-time, which makes it fast.

Ok, thanks for the info. But I have the bundle already generated and on the same local file system, with a source map.

This would make Jest unusable for any browserified project, or am I missing something?

You just run Jest on source files, no need to browserify it, just apply the same babel transforms if necessary.

I am afraid I don't understand.

I browserify code to get rid of Node objects. Then I want to test if this went well. My source files call into package dependencies that themselves call into Node API (like fs.readFileSync).
So I should apply babel transforms, which generates a bundle with the app code. The Jest tests are still in separate files (I am not suggesting to bundle these).

PS The ignite boilerplate is also fitted out with babel-jest so I fully expected it to act on the real app code, not the 'un-transpiled template' that is in the node_modules code on disk.

Sorry for my ignorance, but could you please enlighten me a bit more?

I've had the worst dev experience of my life setting up my RN project, coming from Java. Just spend 2,5 days on setting up debugging. Going through tons of outdated advice and numerous open issues. I know porting packages written for Node is not the easiest thing to start with, but it shouldn't be this hard.

I love the technology, what you guys are doing. I love the simple intuitive approach of Jest. But the barrier of entry to any (non-trivial) project setup is just so high.

So my thinking was:

  • If I use shims, I should test my code against the shimmed dependency tree, not containing transitive dependencies on Node native objects.
  • There are 2 ways of shimming. One is physically altering the whole dependency tree in node_modules (i.e. like rn-nodify does). The other, cleaner way is using babel transforms (i.e. ReactNativify approach)
  • I chose the latter one, and my project creates properly transformed bundles (with first approach you could run Jest directly on the code)
  • Most shims are not one-to-one Node API replacements, some (fs) are complete mocks
  • By running my tests against my ES6 codebase + shimmed deps I can find locations where more patching to shims are needed

So if above thinking is correct (maybe it is not), then Jest should run against the transformed / transpiled code. I don't care whether it dynamically transforms or runs against a pre-build bundle.
I read it does dynamic transformation, and I also have a configured babel-jest in my project that should do the transforming.

Can Jest do this, or is it explicitly designed not to do this (limiting its uses). If yes, how? If no, is this properly documented?

Thanks for your help!

Thanks. I'll find my way.

@aschrijver the general way Jest handles this is by doing the transpilation itself. So you set up transformers in your config that Jest itself uses to do the transpilation.

https://facebook.github.io/jest/docs/configuration.html#transform-object-string-string

An example config for Typescript is here to give you an idea of what this could look like: https://github.com/kulshekhar/ts-jest

In terms of shims, what I _think_ you might be wanting are actually Jest mocks. A Jest mock can step in instead of an actual module when you import or require it.

Does that help at all?

Thanks @blargity I appreciate your feedback!

I might follow up on your transformer suggestion, though I almost started with a different test tool.
On first sight it looks like extra work when my project is already doing transpilation with babel. But I'll have to investigate further. Thx.

I will update the stackoverflow questions I have created for this issue with your additional comments!

Regarding the mocks. No that will not work. I know the dependency will break if I port node-based stuff to android. I have to find the breakages through debugging, and then adjust shims accordingly until everything works. I am not creating isolated unit tests, but I intend to have the unit tests of a number of existing (former node-based) packages working as before after the package is ported.

You can import your shims in a setup file, does that help?

https://facebook.github.io/jest/docs/en/configuration.html#setupfiles-array

Thanks @SimenB for your input.

Well, I don't think this is meant for this purpose, just like in Java I wouldn't put code compilation in the Before and After of my integration tests.

And also my project setup already has done all the plumbing and correctly patched bundle + source map is available when tests start. Why would I need to reconfigure all this?

@cpojer

This is the expected behavior. Jest is supposed to run on source files. On any large codebase, generating a bundle before running tests is too slow, so Jest compiles files just-in-time, which makes it fast.

Is it possible to run tests on bundled code though? I'd like to do this in the final step of my CI so I know the actually code which we will be putting into production is tested, it seems rather flaky otherwise.

Has anyone figured out a solution for this? I am trying to find out if it is possible to run tests on the compiled bundles, instead of running the tests on the base TypeScript files?

Was this page helpful?
0 / 5 - 0 ratings