Continuing the discussion from Is packages-for-everything the solution to all Meteor problems?:
@spicemix: Thanks for starting an intelligent discussion around the app-in-packages methodology. I’m interested to hear opinions around testing in this paradigm.
I’m at my 3rd Meteor based startup, been working with the platform for more than 2 years, built a dozen or so apps in that time. In my most recent project, I finally adopted the all code in packages paradigm. My primary motivation was better testing support.
We’re using the mike:mocha-package
package, and we’re running our tests on CircleCI like meteor test-packages --driver-package respondly:test-reporter
. We have packages like app-logging
, app-init
, app-jobs
and so on. There’s code in our packages which executes when run. As in, we don’t simply declare a function and expose it, the package runs code. It often hooks into Meteor.startup()
, but also executes directly.
The challenge we’re now facing, and the philosophical point I’m grappling with, is how we run our tests, without running our code. I’ve tried searching on the topic of testing the app as packages model, but I can’t find any in depth discussion around it.
I had a couple of ideas:
- Defer all code to run via
Meteor.startup()
, and then stubMeteor.startup()
when running tests. - Only expose functionality from our packages, and move the calling of that functionality into the app itself. So package
foo
exposesFoo()
then the app callsFoo.run()
to “start” or “execute” the package.
Do either of these ideas make sense? Is there a better solution?
This challenge really only appears with background jobs. We don’t want the background jobs to run every time we run our tests. I can’t figure out how to determine if Meteor is running tests or running normally, but even if I could, conditionally disabling code based on that seems very ugly.
In Go, this is a non issue. With Go, you define a main()
function, which gets called when your compiled binary is run. When you load the package for testing, main()
is never called, so the application doesn’t start. Simple. You also get access to package scoped variables in your tests (not true in Meteor). I’m wrestling with the question of how to achieve something similar in Meteor.
Thanks in advance for any suggestions or feedback.