简体   繁体   English

TypeScript:如何测试客户端代码?

[英]TypeScript: How do you test your client-side code?

When I write tests for my in-browser TS code, I hit the following problem. 当我为浏览器中的TS代码编写测试时,我遇到了以下问题。 My "test" code files are located in a separate folder from the "application" code files (an arrangement that I am not willing to give up). 我的“测试”代码文件位于与“应用程序”代码文件不同的文件夹中(我不愿意放弃的安排)。 Therefore, in order to import my "app" modules, I have to do this: 因此,为了导入我的“app”模块,我必须这样做:

    // tests/TS/SubComponent/Module.Test.ts
    import m = module("../../Web/Scripts/SubComponent/Module");

This compiles just fine. 编译得很好。 But when loaded in browser, it will obviously not work, because from the standpoint of RequireJS running in the browser, the module is located at " app/SubComponent/Module " (after being remapped through web server and RequireJS config). 但是当在浏览器中加载时,它显然不起作用,因为从浏览器中运行的RequireJS的角度来看,模块位于“ app / SubComponent / Module ”(在通过Web服务器和RequireJS配置重新映射之后)。

With TS 0.8.3 I was able to pull off this clever trick , but in 0.9.0 it no longer works, because now the compiler doesn't let me treat a module as an interface . 使用TS 0.8.3,我能够实现这个聪明的技巧 ,但在0.9.0中它不再有效,因为现在编译器不允许我将模块视为接口

So the question is: how do you test your client-side code? 所以问题是: 如何测试客户端代码? Clearly, I can't be the only person to be doing it, can I? 显然,我不能成为唯一一个这样做的人,是吗? :-) :-)

I can't tell if you are using Visual Studio - this next bit is Visual Studio specific... 我不知道你是否使用Visual Studio - 下一步是Visual Studio特定的......

This is how I do it: 我是这样做的:

In my test project, I created a folder named "ReferencedScripts" and referenced the scripts from the project being tested (add existing item > add as link). 在我的测试项目中,我创建了一个名为“ReferencedScripts”的文件夹,并从正在测试的项目中引用了脚本(添加现有项目>添加为链接)。 Set the file to copy to the output folder. 将文件设置为复制到输出文件夹。

Source: Include JavaScript and TypeScript tests in Visual Studio . 来源: 在Visual Studio中包含JavaScript和TypeScript测试

Using add-as-link makes the scripts available in your test project. 使用add-as-link使脚本在测试项目中可用。

Not using Visual Studio? 不使用Visual Studio? I recommend creating a task / job / batch file to copy the files into the test folder. 我建议创建一个任务/作业/批处理文件,将文件复制到测试文件夹中。 You could even use tsc to do this task for you. 您甚至可以使用tsc为您执行此任务。

I am in the middle of a project where I have to migrate parts of a large javascript project to typescript and this is how I managed to keep the tests running: 我正处于一个项目的中间,我必须将大型javascript项目的一部分迁移到typescript,这就是我设法保持测试运行的方式:

  1. Use grunt-typescript task to watch and compile all my .ts files from the source to a tmp folder (with their source-maps). 使用grunt-typescript任务来查看和编译我的.ts文件,从源到tmp文件夹(带有源映射)。 If you only have to deal with typescript files, then you can use the tsc in watch mode to do it as well. 如果您只需要处理打字稿文件,那么您也可以在监视模式下使用tsc来执行此操作。 The latter would be faster, but the former allowed me to simultaneous edit javascript and typescript files with livereload. 后者会更快,但前者允许我使用livereload同时编辑javascript和typescript文件。

  2. Include the .ts files in karma.conf but don't watch them or include them: karma.conf包含.ts文件,但不要观察它们或包含它们:

     // list of files / patterns to load in the browser files = [ JASMINE, JASMINE_ADAPTER, // ... // We want the *.js to appear in in the window.__karma__.files list { pattern: 'app/**/*.ts', included: false, watched: false, served: true }, { pattern: 'app/**/*.js', included: false }, // We do watch the folder where the typescript files are compiled { pattern: 'tmp/**/*.js', included: false }, // ... // Finally, the test-main file. 'tests/test-main.js' ]; 
  3. Finally, in the test-main.js file, I mangle the names of typescript files and declare them as require modules with the correct paths (to the corresponding .js file) in test-main.js : 最后,在test-main.js文件中,我test-main.js文件的名称,并将它们声明为需要模块,并在test-main.js使用正确的路径(到相应的.js文件):

     var dynPaths = { 'jquery' : 'lib/jquery.min', 'text' : 'lib/text' }; var baseUrl = 'base/app/', compilePathUrl = '../tmp/'; Object.keys(window.__karma__.files) .forEach(function (file) { if ((/\\.ts$/).test(file)) { // For a typescript file, include compiled file's path var fileName = file.match(/(.*)\\.ts$/)[1].substr(1), moduleName = fileName.substr(baseUrl.length); dynPaths[moduleName] = compilePathUrl + fileName.substr(baseUrl.length); } }); require({ // Karma serves files from '/base' baseUrl: '/' + baseUrl, paths: dynPaths, shim: { /* ... */ }, deps: [ /* tests */ ], // start test run, once requirejs is done callback: function () { window.__karma__.start(); } }); 

Then as I edit the typescript files, they are compiled and put in the tmp folder as javascript files. 然后,当我编辑打字稿文件时,它们被编译并作为javascript文件放在tmp文件夹中。 These trigger karma 's auto watch and it reruns the tests. 这些引发karma的自动监视并重新进行测试。 In the tests, the require calls resolve correctly since we have explicitly overwritten the paths to the typescript files. 在测试中, require调用正确解析,因为我们已经明确地覆盖了typescript文件的路径。

I realise that this is a bit hacky, but I had to jump through similar hoops while trying to include all my tests with REQUIRE_ADAPTER . 我意识到这有点hacky,但我不得不在尝试用REQUIRE_ADAPTER包含所有测试时跳过类似的箍。 So I assumed that there is no cleaner way of doing it. 所以我认为没有更清洁的方法。

Hopefully, if typescript becomes more prevalent, we will see better support for testing. 希望如果打字稿变得更加普遍,我们将看到更好的测试支持。

So here's ultimately what I've done: it turns out that Karma can handle/watch/serve files that are not within the base directory, and it makes them look to the browser in the form of " /absolute/C:/dir/folder/blah/file.js ". 所以这就是我最终所做的事情:事实证明,Karma可以处理/监视/提供不在基本目录中的文件,并且它使它们以“ / absolute / C:/ dir / ”的形式查看浏览器folder / blah / file.js “。 This happens whenever files -> pattern starts with " ../ ". 只要文件 - >模式以“ ../ ”开头,就会发生这种情况。

This feature can be used to make RequireJS see the whole directory structure exactly as it exists on the file system, thus allowing the tests to import app modules in the form of " ../../Web/App/Module.ts ". 此功能可用于使RequireJS完全查看文件系统上存在的整个目录结构,从而允许测试以“ ../../Web/App/Module.ts ”的形式导入应用程序模块。

files = [
  // App files:
  { pattern: '../../Web/App/**/*', watched: true, served: true, included: false },

  // Test files:
  { pattern: '../js/test/**/*.js', watched: true, served: true, included: false }
];

Reference (version 0.8): http://karma-runner.github.io/0.8/config/files.html 参考(版本0.8): http//karma-runner.github.io/0.8/config/files.html

Since the typescript code is compiled to Javascript you can use all Javascript test frameworks. 由于打字稿代码被编译为Javascript,您可以使用所有Javascript测试框架。

I am using Jasmine: https://github.com/pivotal/jasmine/wiki 我正在使用Jasmine: https//github.com/pivotal/jasmine/wiki

You can write your tests in Typescript with the .d.ts file here: https://github.com/borisyankov/DefinitelyTyped/blob/master/jasmine/jasmine.d.ts 您可以使用.d.ts文件在Typescript中编写测试: https//github.com/borisyankov/DefinitelyTyped/blob/master/jasmine/jasmine.d.ts

But my client code is rather small and compiled to one output file, so I don't have the module issues that you describe. 但我的客户端代码相当小,并编译为一个输出文件,所以我没有你描述的模块问题。

Might be that I misunderstood your question - can't comment yet... 可能是我误解了你的问题 - 还不能发表评论......

The runtime of the browser does not need any typescript information. 浏览器的运行时不需要任何打字稿信息。 So your test script should import the compiled ts files the same way as any other javascript files they need. 因此,您的测试脚本应该以与他们需要的任何其他JavaScript文件相同的方式导入已编译的ts文件。 Might be that you have to copy them to a subfolder of your test-project before you run your script. 可能是在运行脚本之前必须将它们复制到测试项目的子文件夹中。

I assume the bigger problem is that you have no interface information. 我认为更大的问题是你没有接口信息。 Why do you want to import these informations instead of referencing them? 为什么要导入这些信息而不是引用它们? Especially since importing them will also occur in the browser. 特别是因为导入它们也会在浏览器中出现。

The Reference will only take place in the IDE , so it does not matter in which folders the interface-files are located. 引用只会在IDE中进行,因此接口文件所在的文件夹无关紧要。

/// <reference path="../../Web/Scripts/SubComponent/Module/References.ts" />

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何使用 NodeUnit 测试客户端代码 - How to test client-side code with NodeUnit 如何同步服务器端和客户端代码? - How do you synchronize server-side and client-side code? 在C#中,如何对客户端用户交互和javascript(jQuery)代码进行单元测试? - In C#, how do I unit-test client-side user interaction and javascript (jQuery) code? 您将如何计算用户对站点客户端的累计访问? - How would you count a user's accumulated visits to your site client-side? 您如何判断网页是客户端渲染还是服务器端渲染 - How do you tell if a web page is client-side or server-side rendering 将MVC模型数据传递到客户端TypeScript代码 - Passing MVC Model Data to Client-side TypeScript Code 如何做高效的客户端认证? - How to do efficient client-side authentication? 客户端 typescript:如何从工厂方法模式中删除循环依赖? - Client-side typescript: how do I remove circular dependencies from the factory method pattern? 如何将服务器端ASP XmlHttpRequest代码转换为客户端JavaScript? - How do I convert my server-side ASP XmlHttpRequest code to client-side JavaScript? 通过搜寻器运行javascript以测试客户端代码 - Running javascript via a crawller to test client-side code
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM