Can I use an environment other than 'test' for Ember tests? - ember.js

I have Ember.js 2.16 acceptance tests written using the Ember template test libraries (QUnit and testem) that test the general functionality of an Ember app. When I run ember test, the 'environment' for which environment variables are retrieved is always set to test.
Is there a way to run ember test with any environment other than test? Running it with --environment="my_other_test_env" doesn't change the environment as it would for ember build or ember serve.
I’d like to be able to pass parameters to acceptance tests depending on what environment they are running in. Is this behavior supported, and if not, is there a reason I shouldn't be doing this? I understand that for lower-level unit testing, I shouldn't be dealing with external dependencies, but for end-to-end acceptance testing, it seems normal that there would be different environments I would want to run the tests in.

You could use your own environment variable:
Run with TEST_ENV=...
$ TEST_ENV=special ember test
Add it to your app configuration:
// config/environment.js
if (environment === 'test') {
ENV.testingEnvironment = process.env.TEST_ENV;
...
}
And use it in your acceptance test like:
import ENV from '../../config/environment';
alert(ENV.testingEnvironment); // outputs 'special'
I'm using similar way to deploy a production build to a staging environment, but only changing some api endpoints in the configuration.

Related

Testing Django Apps On Heroku With Cypress

I'm a hobby web developer looking to build my first product with the django web framework which I will host on Heroku. Cypress looks like a great modern tool for UI testing which I certainly want to use. In local development I am using it within django testing so that the django staticliveservertestcase runs first - which creates a separate development server process, and a test database, if one hasn't been created already. Within this test I then call a bash script which executes a cypress UI test. See the example below.
Bash Script -
#!/bin/bash
echo $1 # the 1st command line argument
echo $2 # the 2nd command line argument
./node_modules/.bin/cypress run --env baseUrl=$1 --spec $2
Django Test Code -
class ExampleTest(StaticLiveServerTestCase):
def test_view_url(self):
from subprocess import run
exit_code = run([
'./cypress/run.sh',
f'http://{self.server_thread.host}:{self.server_thread.port}',
'cypress/integration/sample_spec.js'
])
self.assertEqual(0, exit_code.returncode)
From my understanding this is the opposite to the standard cypress approach. Normally cypress runs outside of the app independently and simply runs through all the tests which interact with the app. Here the cypress tests are called by the django process. Unless I am mistaken there are obvious advantages to this approach. I can test the UI and whether objects where created in the database after the UI test has run.
Is it possible, and if this how, to do this within Heroku? So Heroku would simply call the test script -
python manage.py test
And I get UI testing and unit testing all done in one go. It would also be nice to see the tests running in interactive mode. Which may be a challenge because Heroku obviously runs everything in a linux container - I don't plan on using Docker incidentally because I think that limits a lot of the features Heroku offers.

How can I set up mocha tests to run Ember initializers so injected objects are defined?

My Ember app injects an "i18n" object into the container via an initializer, which is later looked up with "this.container.lookup('i18n:main')" in a controller 'preferredLanguage' computed property.
A mocha unit test which tests the controller 'preferredLanguage' property, fails due to "i18n is not defined". How can I set up the mocha tests to run Ember application initializers so injected objects are defined when looked up from the container during unit testing?
I've found that the main issue is (as you mentioned) is that the start-app.js file doesn't run when mocha is installed. I battled this for a while as well but have finally refined the process to get Ember and Mocha to play nicely. First you have to get ember-cli-mocha and ember-mocha setup correctly. Then you can explicitly import and invoke the startApp function in your tests/test-helper.js file to have Ember run and inject test helpers like it normally does with qunit. Here is what has worked for me with ember-cli 1.13.1.
bower install ember-mocha
bower install ember-test-helpers
npm install ember-cli-mocha
ember install ember-cli-mocha (say Y to overwrite test-helper.js)
Then in tests/test-helper.js
// tests/test-helper.js
import resolver from './helpers/resolver';
import { setResolver } from 'ember-mocha';
// startApp doesn't run with mocha... so we run it explicitly
import startApp from "./helpers/start-app";
startApp();
setResolver(resolver);
After that you can create generate a route or controller and ember-cli-mocha will create test and you should have access to helpers like visit() and currentURL(); Though I found you need to actually setup the route and controller for those to work correctly.
it("should have use of ember's test helpers", function() {
visit("/mocha-test");
andThen(function() {
var url = currentURL();
expect(url).to.equal("/mocha-test");
});
});

Use Forever with Ember-CLI

I've set up a website using Ember-CLI and it is now ready for production, so we're looking for a way to keep it running permanently.
Right now we're using $ ember serve --port 80
but obviously this only works whilst we're logged in. I've used Forever before to keep a node app running but am not sure how to make this work with Ember CLI, as the 'ember serve' command obviously does more than just running app.js?
Any input would be appreciated!
Ember-CLI apps are NOT node apps, they are Browser apps, so you don't need anything special to serve them. To keep and Ember-CLI app running permanently, I suggest doing:
ember build --environment=production
This will perform the necessary build steps so that the code works in browsers (e.g, transpiling ES6 modules) and put the code in the build folder. It will also minify JS files and fingerprint all resources (this only happens when the environment is production).
All you have to to then is put the files inside the dist/ folder on a Web Server.
I suggest Apache or Nginx, but anything will work.
Edit
As Omair Vaiyani pointed out, this might not work in some servers because Ember-CLI
uses the locationType: 'auto' which defaults to 'history'. For that to work, you have to configure your SERVER to serve the ember app from all routes.
What I do, and server me well because I don't have control over the server, is to simply change the locationType to 'hash', which will generate URLs with hashes (http://myemberapp/#/myroute/myid) and will work with any server. Just edit the environment.js file accordingly:
module.exports = function(environment) {
var ENV = {
/* other stuf ... */
locationType: 'hash',
/* other stuf ... */
},
/* other stuff */
```

django nose test, How to initialize a setup before any tests

I'm using django_nose for test django apps,
simply run python manage.py test
But, I wanna do a setup before any tests.
For example, create a file before test start. and then all the tests will using this file.
How to do this?
please help
As mentioned in nose docs, Test modules offer module-level setup and teardown; define the method setup, setup_module, setUp or setUpModule for setup. for e.g. setup_module() function: runs before anything else in the file

How to run Django tests on Heroku

I have a app that is deployed to Heroku, and I'd like to be able to run the test suite post-deployment on the target environment. I am using the Heroku Postgres add-on, which means that I have access to a single database only. I have no rights to create new databases, which in turn means that the standard Django test command fails, as it can't create the test_* database.
$ heroku run python manage.py test
Running `python manage.py test` attached to terminal... up, run.9362
Creating test database for alias 'default'...
Got an error creating the test database: permission denied to create database
Is there any way around this?
Turns out I was in the wrong. I was not testing what I thought was being tested... Since Heroku's Routing Mesh was sending requests to different servers, the LiveServerTestCase was starting a web server on one machine and Selenium was connecting to other machines altogether.
By updating the Heroku Procfile to:
web: python src/manage.py test --liveserver=0.0.0.0:$PORT
overriding the DATABASES setting to point to the test database, and customizing the test suite runner linked to below (the same idea still holds: override setup_databases so that it only drops/re-creates tables, not the entire database), I was able to run remote tests. But this is even more hacky/painful/inelegant. Still looking for something better! Sorry about the confusion.
(updated answer below)
Here are the steps that worked for me:
Create an additional, free Postgres database using the Heroku toolbelt
heroku addons:add heroku-postgresql:dev
Use the HerokuTestSuiteRunner class which you'll find here.
This custom test runner requires that you define a TEST_DATABASES setting which follows the typical DATABASES format. For instance:
TEST_DATABASES = {
'default': dj_database_url.config(env='TEST_DATABASE_URL')
}
Then, have the TEST_RUNNER setting be a Python path to wherever HerokuTestSuiteRunner can be found.
You should now be able to run Django tests on Heroku using the given database. This is very much a quick hack... Let me know how it could be improved / made less hackish. Enjoy!
(original answer below)
A few relevant solutions have been discussed here. As you can read in the Django docs, "[w]hen using the SQLite database engine, the tests will by default use an in-memory database".
Although this doesn't thoroughly test the database engine you're using on Heroku (I'm still on the lookout for a solution that does that), setting the database engine to SQLite will at least allow you to run your tests.
See the above-linked StackOverflow question for some pointers. There are at least two ways out: testing if 'test' in sys.argv before forcing SQLite as the database engine, or having a dedicated settings file used in testing, which you can then pass to django manage.py test using the --settings option.
Starting with version 1.8, Django now has an option called keepdb, which allows for the same database to be reused during tests.
The --keepdb option can be used to preserve the test database between test runs.
This has the advantage of skipping both the create and destroy actions which can greatly decrease the time to run tests, especially those in a large test suite.
If the test database does not exist, it will be created on the first run and then preserved for each subsequent run.
Any unapplied migrations will also be applied to the test database before running the test suite.
Since it also allows for the test database to exist prior to running tests, you can simply add a new Postgres Heroku instance to your dyno and configure the tests to use that particular database.
Bonus : you can also use the failfast option, which exits as soon as your first test crashes, so that you don't have to wait for all tests to complete.
However, if you are deploying things to Heroku and you are using Heroku Pipelines, an even better option is available : Heroku CI.