Jasmine과 함께 작동하도록 requirejs 얻기
먼저 RequireJS를 처음 접했고 Jasmine을 처음 사용했다고 말하고 싶습니다.
SpecRunner에 문제가 있으며 JS가 필요합니다. 나는 Uzi Kilon과 Ben Nadel의 튜토리얼 (다른 사람들과 함께)을 따라 왔고 그들은 일부를 도왔지만 여전히 몇 가지 문제가 있습니다.
테스트에서 오류가 발생하면 (특히 유형 오류를 생각할 수 있음) spec runner html이 표시되는 것 같습니다. 이것은 자바 스크립트에 몇 가지 문제가 있음을 알려줍니다. 그러나이 오류를 수정 한 후에는 더 이상 HTML이 표시되지 않습니다. 테스트 러너가 전혀 표시되지 않습니다. 누군가 내 코드에서이 문제를 일으킬 수있는 문제를 찾을 수 있습니까?
다음은 내 디렉토리 구조입니다 .
Root
|-> lib
|-> jasmine
|-> lib (contains all of the jasmine lib)
|-> spec
|-> src
|-> jquery (jquery js file)
|-> require (require js file)
index.html (spec runner) specRunner.js
다음은 SpecRunner (색인) HTML입니다 .
<!doctype html>
<html lang="en">
<head>
<title>Javascript Tests</title>
<link rel="stylesheet" href="lib/jasmine/lib/jasmine.css">
<script src="lib/jasmine/lib/jasmine.js"></script>
<script src="lib/jasmine/lib/jasmine-html.js"></script>
<script src="lib/jquery/jquery.js"></script>
<script data-main="specRunner" src="lib/require/require.js"></script>
<script>
require({ paths: { spec: "lib/jasmine/spec" } }, [
// Pull in all your modules containing unit tests here.
"spec/notepadSpec"
], function () {
jasmine.getEnv().addReporter(new jasmine.HtmlReporter());
jasmine.getEnv().execute();
});
</script>
</head>
<body>
</body>
</html>
다음은 specRunner.js (config)입니다.
require.config({
urlArgs: 'cb=' + Math.random(),
paths: {
jquery: 'lib/jquery',
jasmine: 'lib/jasmine/lib/jasmine',
'jasmine-html': 'lib/jasmine/lib/jasmine-html',
spec: 'lib/jasmine/spec/'
},
shim: {
jasmine: {
exports: 'jasmine'
},
'jasmine-html': {
deps: ['jasmine'],
exports: 'jasmine'
}
}
});
사양은 다음과 같습니다.
require(["../lib/jasmine/src/notepad"], function (notepad) {
describe("returns titles", function() {
expect(notepad.noteTitles()).toEqual("");
});
});
메모장 소스 :
define(['lib/jasmine/src/note'], function (note) {
var notes = [
new note('pick up the kids', 'dont forget to pick up the kids'),
new note('get milk', 'we need two gallons of milk')
];
return {
noteTitles: function () {
var val;
for (var i = 0, ii = notes.length; i < ii; i++) {
//alert(notes[i].title);
val += notes[i].title + ' ';
}
return val;
}
};
});
그리고 Note 소스 (JIC) :
define(function (){
var note = function(title, content) {
this.title = title;
this.content = content;
};
return note;
});
앱에 관한 한 경로가 올바른지 확인했습니다. 이 작업을 수행하면 그 경로를 구성하여 그렇게 엉뚱하지 않게 할 수 있습니다.
나는 시행 착오를 거쳐 이것을 작동시킬 수 있었다. 주요 문제는 사양을 작성할 때 생성하려는 요구 사항이 아니라 define을 사용하고 싶다는 것입니다.
실물:
require(["/lib/jasmine/src/notepad"], function (notepad) {
describe("returns titles", function() {
expect(notepad.noteTitles()).toEqual("pick up the kids get milk");
});
});
일:
define(["lib/jasmine/src/notepad"], function (notepad) {
describe("returns titles", function () {
it("something", function() {
expect(notepad.noteTitles()).toEqual("pick up the kids get milk ");
});
});
});
몇 가지 조사를 한 후 RequireJS를 사용할 때 require ()가 사용하기를 원하는 모든 것이 정의로 래핑되어야한다는 것이 분명해졌습니다 (지금 당연한 것 같습니다). specRunner.js 파일에서 테스트를 실행할 때 요구 사항이 사용된다는 것을 알 수 있습니다 (따라서 스펙을 "정의"해야합니다.
다른 문제는 사양을 만들 때 describe () 및 it ()이 필요하다는 것입니다 (게시 된 예제에서 설명한 것과 같은 설명뿐 아니라).
실물:
describe("returns titles", function() {
expect(notepad.noteTitles()).toEqual("pick up the kids get milk");
});
일:
describe("returns titles", function () {
it("something", function() {
expect(notepad.noteTitles()).toEqual("pick up the kids get milk ");
});
});
또한 테스트 러너가있는 곳을 변경했지만 이것은 리팩터링이었고 테스트 결과를 변경하지 않았습니다.
다시, 다음은 파일과 변경된 사항입니다.
note.js : 동일하게 유지
notepad.js : 그대로 유지
index.html :
<!doctype html>
<html lang="en">
<head>
<title>Javascript Tests</title>
<link rel="stylesheet" href="lib/jasmine/lib/jasmine.css">
<script data-main="specRunner" src="lib/require/require.js"></script>
</head>
<body>
</body>
</html>
specRunner.js :
require.config({
urlArgs: 'cb=' + Math.random(),
paths: {
jquery: 'lib/jquery',
'jasmine': 'lib/jasmine/lib/jasmine',
'jasmine-html': 'lib/jasmine/lib/jasmine-html',
spec: 'lib/jasmine/spec/'
},
shim: {
jasmine: {
exports: 'jasmine'
},
'jasmine-html': {
deps: ['jasmine'],
exports: 'jasmine'
}
}
});
require(['jquery', 'jasmine-html'], function ($, jasmine) {
var jasmineEnv = jasmine.getEnv();
jasmineEnv.updateInterval = 1000;
var htmlReporter = new jasmine.HtmlReporter();
jasmineEnv.addReporter(htmlReporter);
jasmineEnv.specFilter = function (spec) {
return htmlReporter.specFilter(spec);
};
var specs = [];
specs.push('lib/jasmine/spec/notepadSpec');
$(function () {
require(specs, function (spec) {
jasmineEnv.execute();
});
});
});
notepadSpec.js :
define(["lib/jasmine/src/notepad"], function (notepad) {
describe("returns titles", function () {
it("something", function() {
expect(notepad.noteTitles()).toEqual("pick up the kids get milk");
});
});
});
Jasmine 2.0을 독립형으로 사용하는 사람들을위한 대체 답변으로 이것을 추가하기 만하면됩니다. 나는 이것이 Jasmine 1.3에서도 작동 할 수 있다고 생각하지만 비동기 구문은 다르고 다소 추합니다.
다음은 수정 된 SpecRunner.html 파일입니다.
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Jasmine Spec Runner v2.0.0</title>
<link rel="shortcut icon" type="image/png" href="lib/jasmine-2.0.0/jasmine_favicon.png">
<link rel="stylesheet" type="text/css" href="lib/jasmine-2.0.0/jasmine.css">
<!--
Notice that I just load Jasmine normally
-->
<script type="text/javascript" src="lib/jasmine-2.0.0/jasmine.js"></script>
<script type="text/javascript" src="lib/jasmine-2.0.0/jasmine-html.js"></script>
<script type="text/javascript" src="lib/jasmine-2.0.0/boot.js"></script>
<!--
Here we load require.js but we do not use data-main. Instead we will load the
the specs separately. In short we need to load the spec files synchronously for this
to work.
-->
<script type="text/javascript" src="js/vendor/require.min.js"></script>
<!--
I put my require js config inline for simplicity
-->
<script type="text/javascript">
require.config({
baseUrl: 'js',
shim: {
'underscore': {
exports: '_'
},
'react': {
exports: 'React'
}
},
paths: {
jquery: 'vendor/jquery.min',
underscore: 'vendor/underscore.min',
react: 'vendor/react.min'
}
});
</script>
<!--
I put my spec files here
-->
<script type="text/javascript" src="spec/a-spec.js"></script>
<script type="text/javascript" src="spec/some-other-spec.js"></script>
</head>
<body>
</body>
</html>
이제 여기에 예제 사양 파일이 있습니다.
describe("Circular List Operation", function() {
// The CircularList object needs to be loaded by RequireJs
// before we can use it.
var CircularList;
// require.js loads scripts asynchronously, so we can use
// Jasmine 2.0's async support. Basically it entails calling
// the done function once require js finishes loading our asset.
//
// Here I put the require in the beforeEach function to make sure the
// Circular list object is loaded each time.
beforeEach(function(done) {
require(['lib/util'], function(util) {
CircularList = util.CircularList;
done();
});
});
it("should know if list is empty", function() {
var list = new CircularList();
expect(list.isEmpty()).toBe(true);
});
// We can also use the async feature on the it function
// to require assets for a specific test.
it("should know if list is not empty", function(done) {
require(['lib/entity'], function(entity) {
var list = new CircularList([new entity.Cat()]);
expect(list.isEmpty()).toBe(false);
done();
});
});
});
다음은 Jasmine 2.0 문서의 비동기 지원 섹션 링크입니다. http://jasmine.github.io/2.0/introduction.html#section-Asynchronous_Support
Jasmine 2.0 독립형을위한 또 다른 옵션은 boot.js 파일을 만들고 모든 AMD 모듈이로드 된 후 테스트를 실행하도록 설정하는 것입니다.
우리의 경우 테스트를 작성하는 이상적인 최종 사용자 사례는 모든 사양 파일 또는 종속성을 한 번의 명시 적 목록에 나열 할 필요가없고 * spec 파일을 종속성이있는 AMD 모듈로 선언해야한다는 요구 사항 만있는 것입니다.
이상적인 사양의 예 : spec / javascript / sampleController_spec.js
require(['app/controllers/SampleController'], function(SampleController) {
describe('SampleController', function() {
it('should construct an instance of a SampleController', function() {
expect(new SampleController() instanceof SampleController).toBeTruthy();
});
});
});
Ideally the background behaviour of loading the dependency in and running the specs would be totally opaque to anyone coming on to the project wanting to write tests, and they won't need to do anything other than create a *spec.js file with AMD dependencies.
To get this all working, we created a boot file and configured Jasmine to use it (http://jasmine.github.io/2.0/boot.html), and added some magic to wrap around require to temporarily delay running tests until after we have our deps loaded:
Our boot.js' "Execution" section:
/**
* ## Execution
*
* Replace the browser window's `onload`, ensure it's called, and then run all of the loaded specs. This includes initializing the `HtmlReporter` instance and then executing the loaded Jasmine environment. All of this will happen after all of the specs are loaded.
*/
var currentWindowOnload = window.onload;
// Stack of AMD spec definitions
var specDefinitions = [];
// Store a ref to the current require function
window.oldRequire = require;
// Shim in our Jasmine spec require helper, which will queue up all of the definitions to be loaded in later.
require = function(deps, specCallback){
//push any module defined using require([deps], callback) onto the specDefinitions stack.
specDefinitions.push({ 'deps' : deps, 'specCallback' : specCallback });
};
//
window.onload = function() {
// Restore original require functionality
window.require = oldRequire;
// Keep a ref to Jasmine context for when we execute later
var context = this,
requireCalls = 0, // counter of (successful) require callbacks
specCount = specDefinitions.length; // # of AMD specs we're expecting to load
// func to execute the AMD callbacks for our test specs once requireJS has finished loading our deps
function execSpecDefinitions() {
//exec the callback of our AMD defined test spec, passing in the returned modules.
this.specCallback.apply(context, arguments);
requireCalls++; // inc our counter for successful AMD callbacks.
if(requireCalls === specCount){
//do the normal Jamsine HTML reporter initialization
htmlReporter.initialize.call(context);
//execute our Jasmine Env, now that all of our dependencies are loaded and our specs are defined.
env.execute.call(context);
}
}
var specDefinition;
// iterate through all of our AMD specs and call require with our spec execution callback
for (var i = specDefinitions.length - 1; i >= 0; i--) {
require(specDefinitions[i].deps, execSpecDefinitions.bind(specDefinitions[i]));
}
//keep original onload in case we set one in the HTML
if (currentWindowOnload) {
currentWindowOnload();
}
};
We basically keep our AMD syntax specs in a stack, pop them off, require the modules, execute the callback with our assertions in it, then run Jasmine once everything is done loading in.
This set up allows us to wait until all of the AMD modules required by our individual tests are loaded, and doesn't break AMD patterns by creating globals. There's a little hackery in the fact that we temporarily override require, and only load our app code using require (our `src_dir:
in jasmine.yml is empty), but the overall goal here is to reduce the overhead of writing a spec.
you can use done
in combo with before filters to test asynchronous callbacks:
beforeEach(function(done) {
return require(['dist/sem-campaign'], function(campaign) {
module = campaign;
return done();
});
});
This is how I do to run a jasmine spec in a html using AMD/requirejs for all my sources and specs.
This is my index.html file that loads jasmine and then my 'unit test starter' :
<html><head><title>unit test</title><head>
<link rel="shortcut icon" type="image/png" href="/jasmine/lib/jasmine-2.1.3/jasmine_favicon.png">
<link rel="stylesheet" href="/jasmine/lib/jasmine-2.1.3/jasmine.css">
<script src="/jasmine/lib/jasmine-2.1.3/jasmine.js"></script>
<script src="/jasmine/lib/jasmine-2.1.3/jasmine-html.js"></script>
<script src="/jasmine/lib/jasmine-2.1.3/boot.js"></script>
</head><body>
<script data-main="javascript/UnitTestStarter.js" src="javascript/require.js"></script>
</body></html>
and then my UnitTestStarter.js is something like this:
require.config({
"paths": {
....
});
require(['MySpec.js'], function()
{
jasmine.getEnv().execute();
})
참고URL : https://stackoverflow.com/questions/16423156/getting-requirejs-to-work-with-jasmine
'Program Tip' 카테고리의 다른 글
IntelliJ IDEA 용 Visual Studio ReSharper 키맵 (0) | 2020.11.15 |
---|---|
D3로 "실시간"그래프 생성 (0) | 2020.11.15 |
배열의 경우 push () 또는 pop ()과 동일합니까? (0) | 2020.11.15 |
.Wait () 대 .GetAwaiter (). GetResult ()의 차이점은 무엇입니까? (0) | 2020.11.15 |
연동 및 휘발성 (0) | 2020.11.15 |