针对远程 URL 对本地 JavaScript 文件进行单元测试

Unit test a local JavaScript file against a remote URL

如何针对远程 URL 对本地 JavaScript 文件进行单元测试?我已经断断续续地研究了几天,但还不太明白。

我有一个本地文件,具有 DOM 操作,例如一个名为 app.js 的文件,其中包含:

document.querySelector('p').textContent = 'This is a test.';

然后如何针对远程 URL(例如 http://example.com/)进行测试,以确保代码成功 运行s? URL 不是我控制的。也许包含 Selenium 的解决方案最有意义,但我不确定如何 运行 我的本地 JS 文件与远程 URL.

例如这个伪代码:

openUrl('http://example.com/', function() {
  inject('./app.js');

  element = document.querySelector('p');

  assertEquals('This is a test.', element.textContent);
});

我尝试使用 Casper JS(基于 Phantom JS),这是最有希望的,但它不会等待 DOM 在 运行ning 断言之前完成加载,所以jQuery $(document).ready() 块中的任何内容都不会执行。

这是到目前为止我在 Casper JS 中得到的;第二个断言失败,因为它 运行 在 ready() 块中。

// app.js
$ = require('jquery');

$('p').first().text('test');

$(document).ready(function() {
  $('h1').text('one');
});

并且:

// test.js
var url = 'http://example.com/';
var script = 'Example/app.js';

casper.test.begin('Test', function suite(test) {
  casper.start(url, function() {
    casper.page.injectJs(script);

    // 'test' was added immediately, in app.js. This succeeds.
    test.assertTextExists('test');

    // 'one' runs in a $(document).ready() block. This assertion fails.
    test.assertTextExists('one');
  });

  casper.run(function() {
    test.done();
  });
});

检查 phantom.js 它是一个无头浏览器,可以加载 url,运行 jquery,如果你愿意,可以做断言。

然后您可以测试您的本地环境,运行同样的脚本也适用于远程。

phantom.js 非常流行,有很多插件可用。

我最终使用了 Casper,我通过简单地使用 casper.wait(100).

解决了等待 DOM 的问题

一些示例代码(我没有对此进行测试,但它应该可以工作;我的实际代码要复杂得多)。 运行 和 casperjs test casper.js

casper.js

// Begin test suite.
casper.test.begin('Example', function(test) {
  // Start Casper.
  casper.start();

  // Open URL.
  casper.thenOpen('http://example.com/', function() {
    casper.page.injectJs('inject.js');
  });

  // Call the test. Wait for code to finish first.
  casper.wait(100, function() {
    test.assertExists('.element-added-by-injection');
  });

  // A second URL can even be opened.
  casper.thenOpen('http://google.com/', function() {
    casper.page.injectJs('google.js');
  });

  casper.wait(100, function() {
    test.assertExists('.another-element-we-added');
  });

  casper.run(function() {
    test.done();
  });
});

inject.js

var $ = require('jquery');

$(function() {
  $('p').after('<div class="element-added-by-injection">Test</div>');
});