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

feat(regex-mutator): smart regex mutations #2709

Merged
merged 4 commits into from
Jan 24, 2021
Merged

feat(regex-mutator): smart regex mutations #2709

merged 4 commits into from
Jan 24, 2021

Conversation

nicojs
Copy link
Member

@nicojs nicojs commented Jan 22, 2021

This PR adds support for smart regex mutations to Stryker. 👽

Some examples:

/\d{4}\s[a-Z]{2}/;
// Mutates to:
/\d\s[a-Z]{2}/; // => Quantifier removal
/\D{4}\s[a-Z]{2}/; // => Predefined Character Class Negation
/\d{4}\S[a-Z]{2}/; // => Predefined Character Class Negation
/\d{4}\s[a-Z]/; // => Quantifier removal
/\d{4}\s[^a-Z]{2}/; // => Character Class Negation

Stryker will identify regex literals: /\d{4}\s[a-Z]{2}/ as well as clear regex string literals in a RegExp constructor: new RegExp('\\d{4}\\s[a-Z]{2}'). After that it uses the awesome Weapon-regeX library to generate mutants based on the regex pattern. These mutants are then placed inside the code with regular mutation switching practises.

Weapon regex supports mutation levels. Currently, Stryker only introduces regex mutants of mutation level 1 in your code. We might be making this configurable in the future.

Note: this mutator might have a significant impact on your mutation score, depend on whether or not you use regexes a lot and how well you've been testing them 😉.

You can opt-out of using this mutator by excluding it via stryker.conf.json:

{
  "mutator": {
    "excludedMutations": ["Regex"]
  }
}

@nicojs nicojs force-pushed the feat/weapon-regex branch from 57d5f2a to 558d183 Compare January 22, 2021 17:25
@nicojs nicojs force-pushed the feat/weapon-regex branch from 32e9112 to 58ea75b Compare January 22, 2021 19:37
@nicojs nicojs changed the title feat(regex-mutator): enable regex mutator feat(regex-mutator): enable regex mutations Jan 22, 2021
@nicojs nicojs changed the title feat(regex-mutator): enable regex mutations feat(regex-mutator): enable smart regex mutations Jan 22, 2021
@nicojs nicojs changed the title feat(regex-mutator): enable smart regex mutations feat(regex-mutator): smart regex mutations Jan 22, 2021
@nicojs nicojs marked this pull request as ready for review January 22, 2021 20:14
@wijtserekker
Copy link
Contributor

Looks very clean! Nice to see Weapon regeX found a home in stryker 😄. I am a little sad that you mutate only on level 1, but I guess users otherwise drown in mutants by default.

path.parentPath.node.arguments[0] === path.node
);
}
const weaponRegexOptions: weaponRegex.Options = { mutationLevels: [1] };
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The mutation levels are designed so that the tests get more specific as the mutation level increases. If a test suite can kill the mutants at some level, then it should also kill all mutants at lower mutation levels. So if you want to keep it simple with only one level, then go for level 3.
Other than that, it looks awesome 🎉

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the feedback!

I know this is true, but it would also generate a lot more mutants. That means a bigger hit on performance as well as it representing a bigger piece of the mutation score pie. This first inclusion of the Regex mutator is just the beginning. I want to first see how our users react first before I go all out.

In the end, I want to implement mutation levels Stryker-wide. So each mutator can use them and this is a way for us to add new mutators without a big hit on performance. Stryker.NET already started with this, but they currently use their gut-feeling to choose which mutator provides which mutant level. I'm preparing a new graduation assignment that should investigate this further and implement this as a proof of concept.

I hope you're not disappointed. As you can see, we're definitely planning to implement level 2 and level 3, but with this first release I want to add value for users of Stryker fast and improve on that later.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not at all, it's totally understandable 😉

@nicojs nicojs merged commit 0877f44 into master Jan 24, 2021
@nicojs nicojs deleted the feat/weapon-regex branch January 24, 2021 20:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants