-
Notifications
You must be signed in to change notification settings - Fork 12k
Support mutation testing with angular cli #8744
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
Comments
I read about what you guys are doing and think it's pretty cool! I'm not familiar with what I think it should be possible to just leave the server open. I mean, you can do that right now by simply running Ultimately it's karma itself that closes the server so this is mostly a matter of configuring karma itself to stay open. |
@filipesilva thanks for your interest and kind words I had to look it up myself as well. With This is only part of the solution though, as we also need exact test results (inc code coverage results per test if we can). We manage this with karma because we use karma's pubic api (with a custom coverage reporter) to start the karma server and report the results back to us. To summarize: we're looking for this kind of api: import * as ng from 'angular-cli';
// Start a test runner. This in turn should load webpack and other plugins karma needs to run the tests
const testRunner = ng.test({
baseDir: 'sandbox/directory/for/this/testRunner',
karmaConfig: { /*override karma config*/ plugins: [{
'reporter:rawCoverage': ['type', RawCoverageReporter]
},
reporters: [ 'rawCoverage' ]
}
});
// Forward karma's events so we can collect the data we need
testRunner.on('spec_complete', (browser, spec) => {} );
testRunner.on('run_complete', (browser, runResult) => {} );
testRunner.on('browser_error', (browser, error) => {} );
testRunner.on('raw_coverage_complete', (browser, error) => {} ); // => a custom event that we report from the RawCoverageReporter
// A way to signal we want a new test run to start
testRunner.run(); That way we can write mutated typescript code to the sandbox directory (directory where we keep a copy of your source code), and signal a new test run (we run multiple sandboxes in parallel for performance reasons).
True, however it doesn't seem to be possible to set Another way of working would be to do all of the work the angular cli is doing ourselves. @Archcry did an awesome proof of concept project here: https://github.com/Archcry/stryker-angular-extra. Here, he basically mimics the angular cli build functionality using the stryker-webpack-transpiler in combination with the stryker-karma-runner. The problem with this approach is that it duplicates the angular-cli test functionality in Stryker, thus i feel it is not maintainable in the long run. However, it might be a sollution if there is a way to pull the entire webpack configuration from angular-cli at runtime (I don't know if that is even possible, with the setup angular-cli is using with regards to webpack and karma). I hope this clears for you. Don't hesitate to ask more questions. We also have a technical reference page on our website. Thanks for the help! |
I had some time to think about it in the hope of finding something less intrusive for angular-cli and yet maintainable for us (the Stryker team). I might have a solution. Would it be possible to use @angular/cli to create a webpack compiler object for us? It would basically look like an
@filipesilva do you think that's possible? If you give us some pointers, maybe we can help with a PR on your side? |
Also see: @filipesilva you've stated about https://angular.io/guide/webpack:
What does that mean exactly? Is it deprecated because it might break in the future based on current development? Or is it deprecated because you're not maintaining the docs anymore? We would like to use this approach as we know it works, but we wouldn't want to build a solution based on something that we know we cannot support. |
I mean that specific guide (the webpack one) is deprecated and not being maintained anymore. I suppose it still works but it's been a while since it was updated. The page is still live but not linked to from anywhere IIRC. We do not maintain the plugins used in that example either. |
@filipesilva thanks for your feedback. Just one more question. You also stated this yesterday:
I believe this is the case for the EDIT: It sure looks like it is. If I add this line in my webpack.config everything seems to work: webpackConfig.module.rules.forEach(rule => {
if (rule.loader === '@ngtools/webpack') {
delete rule.loader;
rule.loaders = [
{
loader: 'awesome-typescript-loader',
options: {
configFileName: path.join(process.cwd(), 'src', appConfig.testTsconfig)
}
}, 'angular2-template-loader'
]
}
}); |
|
Cool! This approach seems to be working. I will create an example which uses private angular cli apis to build a webpack config. Once I have that, I will propose a public api here. @filipesilva thanks for all your afford up until now. 💐 |
No problem at all. I think what you all are doing is super cool 😄 Sorry it wasn't more straightforward to integrate. |
@filipesilva See line 3 to 17 in the webpack config. We use private angular-cli apis to reconstruct the webpack config: Would it be OK to move all that into a single public api call? That would be great as it would allow users to simplify their webpack config used for Stryker, as well as make sure the API doesn't break between patch and minor releases. EDIT: I think the api could look something like this: import { buildTestWebpackConfig, getAppFromConfig } from '@angular/cli';
const appConfig = getAppFromConfig(undefined /* app name */);
const webpackConfig = buildTestWebpackConfig(appConfig ); |
@filipesilva stryker-webpack-transpiler has been released! See https://github.com/nicojs/angular-stryker-example where I explain how to use it for Anguler. As a next step, I would like to work on the changes in the angular cli public api. Could you please share your thoughts my comment above? Thanks! |
Since the last time we spoke I see a lot of changes in your code. My setup is not working anymore for angular 6 (see nicojs/angular-stryker-example#3). It was always supposed to be a temp solution anyway. I've got a 2 questions:
|
Heya @nicojs, we've been making a lot of changes in V6, yes. Notably, in angular/devkit#525 we added support for completely using a virtual file system there. I think this is ultimately what you needed. We pass it in here There isn't a super easy way to build the configuration we pass on to Karma, no. The best I can say is that we have separated how we build it here Since we've moved to the new Architect based builders (what's in the new But I have to warn you that the Architect APIs are experimental and will change in the next few months, so please proceed at your own risk. |
@filipesilva old friend, hope you're having a good day! Thanks for the quick response. There is still a chicken-and-egg problem, as the angular-compiler-plugin seems to always override any existing fs with his own here: https://github.com/angular/devkit/blob/d715cc9149bd811278a5ac53c8ab1f597bb0c9ed/packages/ngtools/webpack/src/angular_compiler_plugin.ts#L581-L585. This will override our own virtual fs here: https://github.com/stryker-mutator/stryker/blob/a6029269e1b37f64febabb6d843031ee14eacc56/packages/stryker-webpack-transpiler/src/compiler/WebpackCompiler.ts#L19-L22. This requires some more thinking. About the building of the webpack configuration using a Stryker builder, how would that work with the architect api? Is there some documentation on the topic? |
Honestly, I'm thinking of using this to capture karma config and webpack config: function captureKarmaConfig() {
return new Promise(res => {
require.cache[require.resolve('karma')] = {
exports: {
Server: function (options, cb) {
process.nextTick(cb);
return {
start() {
res(options);
}
}
}
}
};
process.argv = ['node', require.resolve('@angular/cli'), 'test', '--watch=false'];
require('@angular/cli/bin/ng');
});
} It is ugly... I agree, but at least it uses the public api ( For the chicken-and-egg problem, I now see that you use the passed input filesystem to decorate with the |
@filipesilva I've tried to use the I've traced down the creation of the typescript compiler host. Which is done here: https://github.com/angular/compiler-cli-builds/blob/c2775bba125e9ed40ba60eed4bc6467ffaacf01c/src/ngtools_api2.js#L41. How is the typescript compiler instance supposed react on changes in the virtual file system? I've tried to use the angular_compiler_plugin with angular 6, but with the same results as 6 months ago, namely a mutation score of 0%. So it seems that changes in the in-memory fs still do not propagate to the typescript compiler host. Reverting back to my PoC implementation (awesome-ts-loader) works fine. Can you confirm that this is the case? |
Hi again 👋 I've got some good news. I've decided on another approach, implemented it and released it. It works 👍 However, it relies on a private api: import { cli } from '@angular/cli';
cli({
cliArgs: ['test', '--progress=false', /* ...etc */],
inputStream: process.stdin,
outputStream: process.stdout
}); @filipesilva would that be OK? To use angular with mutation testing, you can use this guide: https://github.com/stryker-mutator/stryker-handbook/blob/master/stryker/configuration/angular.md Basically it works like this:
The implementation is based on the intellij karma plugin, which also executes Thanks for making this possible by merging #11181 |
Heya @nicojs, I think that would be a nice addition, yes. We've recently added another binary as an API too in #12022. I'd ask you to use roughly the same approach as https://github.com/angular/angular-cli/blob/master/packages/angular_devkit/benchmark/src/main.ts uses. Also, you might be interested in karma-runner/karma#3153. We'd like that functionality in so that we can test Karma rebuilds, and I think it might be relevant for you too since there's a lot of tooling involved in Stryker. |
This looks interesting and karma-runner/karma#3153 was merged. Is there anything to do here to get it working with Jest? |
What do you mean? You mean mutation testing with Jest? It is already support via the @stryker-mutator/jest-runner. For anyone else, Stryker does support @angular/cli projects with the [karma.projectType = 'angular-cli'] ](https://github.com/stryker-mutator/stryker/tree/master/packages/karma-runner#karmaprojecttype-custom--angular-cli. Closing this issue. |
@nicojs Because we're using Jest within Angular CLI via nrwl/nx: https://github.com/nrwl/nx so not sure if there's anything else to do there |
Aha, that is completely new for me. It might work out-of-the-box if you create a If you create the jest.config.js file, you should be able to run jest from the command line directly, instead of relying on Note: if it does work, feel free to add the use case to https://github.com/stryker-mutator/stryker-handbook/tree/master/stryker/guides |
Aha, that is completely new for me. Is this related to stryker-mutator/stryker-js#1620 ? If so, we will probably support it in the near future. |
The builder that @intellix mentioned is actually from @nrwl/nx but it's fundamentally the same. You can see the source code here: https://github.com/nrwl/nx/blob/master/packages/jest/src/builders/jest/jest.impl.ts As you can see, it's quite simple. Basically proxies into jest. |
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
We're investigating the possibility of supporting angular in Stryker, a mutation testing framework. I was wondering if it was possible to run test with
ng test --watch=false --single-run=false
and keep open the karma server so we can firekarma run
commands.The idea would be that we make small code changes and rerun the tests with
karma run
. Ideally we would be able to distinguish between a failed test and a compile error.The text was updated successfully, but these errors were encountered: