Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for writing tests in TypeScript #422

Closed
cyberw opened this issue Dec 18, 2017 · 15 comments
Closed

Support for writing tests in TypeScript #422

cyberw opened this issue Dec 18, 2017 · 15 comments
Assignees
Labels
enhancement evaluation needed proposal needs to be validated or tested before fully implementing it in k6 feature help wanted js-compat refactor triage

Comments

@cyberw
Copy link

cyberw commented Dec 18, 2017

It would be really nice to be able to write test cases in TypeScript instead of plain javascript. I miss static typing/compile time checks.

I think this could be accomplished by just creating TS declaration files for the k6 functions that are exposed to the test and publishing them to https://github.com/DefinitelyTyped/DefinitelyTyped

Some more context: We’re looking at being able to use code for API calls based on code generated from a Swagger API definition, so the test case can call something like:

customer.addOrder(“pizza”, 1)

instead of

http.post(“http://some-api-endpoint/customer/orders“, { “name”: “pizza”, “quantity”: 1 })

We could of course generate pure javascript but then that doesn't give us type checks or anything like that, so we wouldnt get IDE support & it would be easier to make mistakes.

@liclac
Copy link
Contributor

liclac commented Dec 18, 2017

I'm definitely open to this, but someone would have to PR a change to js/compiler that would allow it to handle .ts files.

@dstpierre
Copy link
Contributor

I think this should be pre-processed via the installed TypeScript compiler on the host instead of bundling the TS compiler inside k6.

A first check to detect if the script passed is .ts than tsc <script>.ts and the transpiled <script>.js would be used as normal in k6.

The TypeScript definition file would simply help the experience writing the tests in code editors.

I'd like to have a look at this.

@cyberw
Copy link
Author

cyberw commented Dec 19, 2017

I've spent some time on it (using tsc as a preprocessor). I'll describe what I've done, in case you are interested:

In my case, merchant-api.ts is a library generated from a Swagger api definition using a code gen (or at least will be, because right now it is just a placeholder that exports a type and a class, later I will tweak it so that the library is the one actually calling k6's http functions)

I got it working, but the import statement is a little messed up, so I need to manually replace "./merchant-api" with "./merchant-api.js" in the js before k6 accepts it (otherwise I get ERRO[0000] GoError: open /Users/lars.holmberg/git/k6/merchant-api: no such file or directory)

var k6 = require("k6");
var http = require("k6/http");

import {address, MerchantAPI} from "./merchant-api";

export default function() {
// this would fail at compile time - type safety :)
//    var v = new MerchantAPI(45);
    var v = new MerchantAPI("http://www.google.com/");

    console.log(v.createOrderMerchantURL({body: <address>({ organization_name: "Foo Corp" })}));
    var payload = ''
    var params =  { headers: { "Content-Type": "application/json" } }

    let res = http.post(v.getDomain(), payload, params);
    k6.check(res, {
        "is status 200": (r) => r.status === 200
    });
};

I run it this way (you also need a tsconfig.json and lots of other stuff, probably also npm install @types/node --save-dev)

tsc && sed -i '.bak' 's/merchant-api"/merchant-api.js"/' typescript.js && k6 run typescript.js

@liclac
Copy link
Contributor

liclac commented Dec 19, 2017

The import change is on purpose, because otherwise we open for a distinction between how relative imports work locally vs remotely (you can import straight from URLs). Having to add .js felt like a small price to pay for that.

@cyberw
Copy link
Author

cyberw commented Dec 20, 2017

Makes sense. I'm actually quite ok with the way it works now.

Type info would still be nice (and higher prio than adding ts support in js/compiler imho), but because I can force TS to accept the un-typed calls, this is not blocking me any more (I have two full days of TS experience now :)

@aaronmell
Copy link

aaronmell commented Mar 28, 2018

So one thing that I could not get to work was making my main test file a ts file. The imports for k6 and http won't work in TS unless you disregard the TSC failure, as it still emits the js files.

I ended up making my main test file a js file to get around this, and additional modules I created to support testing were ts files. This allowed my unit tests to target my modules, and everything seemed to work okay.

One complication I did run into though, which isn't really solvable I think loading k6/http and check from other ts modules same issue there, and also would break the tests. I wanted to separate the low level test steps from the test file, for reuse in standard integration tests.

@kkeranen
Copy link

liclac wrote:

The import change is on purpose, because otherwise we open for a distinction between how relative imports work locally vs remotely (you can import straight from URLs). Having to add .js felt like a small price to pay for that.

This seems like a show stopper for our case. I tried to make my main script file in JS, but due to complex login system I needed to import our libraries written in TypeScript to login in tests. These libraries are added via NPM. It's not enough to compile TS modules to JS via TSC because I would have to manually add ".js" in all the used TS modules, which is virtually impossible as the import dependencies goes rather deep. I started adding ".js" manually but at some point the dependencies go to code that is out of my control. And then I get the error ERRO[0001] GoError "The system cannot find the file specified." or ERRO[0008] GoError: "The file couldn't be found on local disk".

The bottom line is: k6 doesn't work even with with JS modules, unless the JS modules (including all imports in the chain) are maintained by you so that you can manually change the imports in the code.

@grahamyork
Copy link

Can I just add my voice to the others who are asking for this feature. Great idea!

@Toub
Copy link

Toub commented May 16, 2020

A k6-typescript template based on https://github.com/k6io/k6-es6 would be awesome.

@Toub
Copy link

Toub commented May 17, 2020

Looks like there is a good example of typescript integration here: https://github.com/go-automate/k6-typescript-framework

Edit: see also: https://medium.com/better-programming/performance-testing-in-typescript-5b5444510b83

@ppcano
Copy link
Contributor

ppcano commented Oct 1, 2020

A k6-typescript template based on https://github.com/k6io/k6-es6 would be awesome.

There is a project template at https://github.com/k6io/template-typescript

And the TypeScript definition https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/k6

@mstoykov I think this issue can be closed. If anyone wants any specifics, I suggest creating a new issue.

@Toub
Copy link

Toub commented Oct 1, 2020

Looks good!

What about adding a link to this template from the documentation?

@ppcano
Copy link
Contributor

ppcano commented Oct 1, 2020

What about adding a link to this template from the documentation?

Yes!, It is on Examples page and soon on the Modules page -> grafana/k6-docs#123

Hopefully, users can find the project template. I will figure out if there are other places to add it.

@mstoykov
Copy link
Contributor

mstoykov commented Oct 1, 2020

I am closing this as well then. Thanks @ppcano

@mstoykov mstoykov closed this as completed Oct 1, 2020
@ShradhaKhard
Copy link

I am just wondering, how do I run the K6 tests without using webpack? After running tsc I can see the transpiled .JS files. but when I run the test.js that I have (which imports functions from other files) It fails to run with GoError: The moduleSpecifier "../K6LoadTest/actions/actions" couldn't be found on local disk.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement evaluation needed proposal needs to be validated or tested before fully implementing it in k6 feature help wanted js-compat refactor triage
Projects
None yet
Development

No branches or pull requests