Unit tests with qunit

Hi I’m new to ember and not sure why I’m getting this error You cannot use the same root element (#ember-testing) multiple times in an Ember.Application

I tried removing my other tests to isolate just this one but no luck.

import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';

module('Integration | Component | display, function(hooks) {
  setupRenderingTest(hooks);

  test('Color values', async function(assert) {
    const someThing = this.owner.lookup('component:display');
    colorOptions2 = [
    { name: "Blue", value: 1 },
    { name: "Pink", value: 2 },
  ];
    assert.equal(someThing.colorOptions, colorOptions2);
  });
});

And I have a file called display.hbs and display.js.

Normally that error shows up when a test doesn’t clean up correctly. Here, though, I think there are a couple other issues that are more fundamental with this test.

First, you don’t really want to “unit” test a component, because its public interface is the DOM it renders and any user interactions (normally triggered via actions)—and you always want to test the interface! Partly for that reason, you actually cannot do this kind of “unit”-style test against a Glimmer component.

Second, I’m guessing these are just errors in how you wrote up this sample code, but this test code isn’t actually passing these values to the component in any way, and you’re missing a closing quote on the name of the test.

Combining these, you should end up with something like this:

import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';

module('Integration | Component | display', function(hooks) {
  setupRenderingTest(hooks);

  test('Color values', async function(assert) {
    this.colorOptions = [
      { name: "Blue", value: 1 },
      { name: "Pink", value: 2 },
    ];

    await render(hbs`<Display @colorOptions={{this.colorOptions}} />`);

    let names = find('[data-test-name]');
    assert.equal(names[0].innerText, colorOptions[0].name);
    assert.equal(names[1].innerText, colorOptions[1].name);
  });
});

Here, I’m assuming that you render the data in the component into items which have the attribute data-test-name. For example, if you were iterating over these items in a list, it might look like:

<ul>
  {{#each @colorOptions as |color|}}
    <li>
      <span data-test-name>{{color.name}}</span>:
      <span data-test-value>{{color.value}}</span>
    </li>
  {{/each}}
</ul>

(I named the selector data-test-name because it’s a conventional way to name selectors like that in Ember apps, and most apps use ember-test-selectors so that you can use those kinds of selectors for your tests but strip all of them out of your production builds.)

With those changes, you should have a working component test. If that doesn’t work, please write up further details here!

Thanks for going through that!

My template has a power select box and the component stores the options for powerselect as the object ‘colourOptions’ in the .js. Would that be possible to really test through component testing?

edit: seems like I can use power select integration tests if its possible to add a class name to them

Indeed, it should be! Additionally, power-select may support passing other HTML attributes (I haven’t looked in a long while so don’t recall). Either way, you should be able to do it purely via a rendering test that way, yes!

1 Like