{"id":34931421,"url":"https://github.com/avito-tech/go-mutesting","last_synced_at":"2026-04-09T00:32:03.973Z","repository":{"id":45079861,"uuid":"328627709","full_name":"avito-tech/go-mutesting","owner":"avito-tech","description":"Mutation testing for Go source code. Fork from https://github.com/zimmski/go-mutesting","archived":false,"fork":false,"pushed_at":"2025-12-26T18:35:03.000Z","size":356,"stargazers_count":200,"open_issues_count":13,"forks_count":21,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-12-28T02:15:04.047Z","etag":null,"topics":["golang","mutation-testing"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/avito-tech.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2021-01-11T10:30:34.000Z","updated_at":"2025-12-26T13:02:21.000Z","dependencies_parsed_at":"2024-06-18T18:23:24.197Z","dependency_job_id":"2a702e3c-2f8c-4cfb-9794-0d07ab22a714","html_url":"https://github.com/avito-tech/go-mutesting","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/avito-tech/go-mutesting","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avito-tech%2Fgo-mutesting","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avito-tech%2Fgo-mutesting/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avito-tech%2Fgo-mutesting/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avito-tech%2Fgo-mutesting/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/avito-tech","download_url":"https://codeload.github.com/avito-tech/go-mutesting/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/avito-tech%2Fgo-mutesting/sbom","scorecard":{"id":218381,"data":{"date":"2025-08-11","repo":{"name":"github.com/avito-tech/go-mutesting","commit":"3ce278f4e19feff59232667ce0f8f7fa702c59ba"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":4.8,"checks":[{"name":"Code-Review","score":10,"reason":"all changesets reviewed","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/makefile.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/makefile.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/avito-tech/go-mutesting/makefile.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/makefile.yml:22: update your workflow using https://app.stepsecurity.io/secureworkflow/avito-tech/go-mutesting/makefile.yml/master?enable=pin","Info:   0 out of   2 GitHub-owned GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 30 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-17T02:03:49.467Z","repository_id":45079861,"created_at":"2025-08-17T02:03:49.467Z","updated_at":"2025-08-17T02:03:49.467Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31579900,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-08T14:31:17.711Z","status":"ssl_error","status_checked_at":"2026-04-08T14:31:17.202Z","response_time":54,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["golang","mutation-testing"],"created_at":"2025-12-26T16:22:26.487Z","updated_at":"2026-04-09T00:32:03.955Z","avatar_url":"https://github.com/avito-tech.png","language":"Go","readme":"# go-mutesting [![GoDoc](https://godoc.org/github.com/avito-tech/go-mutesting?status.png)](https://godoc.org/github.com/avito-tech/go-mutesting) [![Build Status](https://travis-ci.org/avito-tech/go-mutesting.svg?branch=master)](https://travis-ci.org/avito-tech/go-mutesting) [![Coverage Status](https://coveralls.io/repos/avito-tech/go-mutesting/badge.png?branch=master)](https://coveralls.io/r/avito-tech/go-mutesting?branch=master)\n\ngo-mutesting is a framework for performing mutation testing on Go source code. Its main purpose is to find source code, which is not covered by any tests.\n\n## Quick example\n\nThe following command mutates the go-mutesting project with all available mutators.\n\n```bash\ngo-mutesting github.com/avito-tech/go-mutesting/...\n```\n\nThe execution of this command prints for every mutation if it was successfully tested or not. If not, the source code patch is printed out, so the mutation can be investigated. The following shows an example for a patch of a mutation.\n\n```diff\nfor _, d := range opts.Mutator.DisableMutators {\n\tpattern := strings.HasSuffix(d, \"*\")\n\n-\tif (pattern \u0026\u0026 strings.HasPrefix(name, d[:len(d)-2])) || (!pattern \u0026\u0026 name == d) {\n+\tif (pattern \u0026\u0026 strings.HasPrefix(name, d[:len(d)-2])) || false {\n\t\tcontinue MUTATOR\n\t}\n}\n```\n\nThe example shows that the right term `(!pattern \u0026\u0026 name == d)` of the `||` operator is made irrelevant by substituting it with `false`. Since this change of the source code is not detected by the test suite, meaning the test suite did not fail, we can mark it as untested code.\n\nThe next mutation shows code from the `removeNode` method of a [linked list](https://github.com/avito-tech/container/blob/master/list/linkedlist/linkedlist.go) implementation.\n\n```diff\n\t}\n\n\tl.first = nil\n-\tl.last = nil\n+\n\tl.len = 0\n}\n```\n\nWe know that the code originates from a remove method which means that the mutation introduces a leak by ignoring the removal of a reference. This can be [tested](https://github.com/zimmski/container/commit/142c3e16a249095b0d63f2b41055d17cf059f045) with [go-leaks](https://github.com/zimmski/go-leak).\n\n## \u003ca name=\"table-of-content\"\u003e\u003c/a\u003eTable of content\n\n- [What is mutation testing?](#what-is-mutation-testing)\n- [How do I use go-mutesting?](#how-do-i-use-go-mutesting)\n- [How do I write my own mutation exec commands?](#write-mutation-exec-commands)\n- [Which mutators are implemented?](#list-of-mutators)\n- [Other mutation testing projects and their flaws](#other-projects)\n- [Can I make feature requests and report bugs and problems?](#feature-request)\n\n## \u003ca name=\"what-is-mutation-testing\"\u003e\u003c/a\u003eWhat is mutation testing?\n\nThe definition of mutation testing is best quoted from Wikipedia:\n\n\u003e Mutation testing (or Mutation analysis or Program mutation) is used to design new software tests and evaluate the quality of existing software tests. Mutation testing involves modifying a program in small ways. Each mutated version is called a mutant and tests detect and reject mutants by causing the behavior of the original version to differ from the mutant. This is called killing the mutant. Test suites are measured by the percentage of mutants that they kill. New tests can be designed to kill additional mutants.\n\u003e \u003cbr/\u003e-- \u003ccite\u003e[https://en.wikipedia.org/wiki/Mutation_testing](https://en.wikipedia.org/wiki/Mutation_testing)\u003c/cite\u003e\n\n\u003e Tests can be created to verify the correctness of the implementation of a given software system, but the creation of tests still poses the question whether the tests are correct and sufficiently cover the requirements that have originated the implementation.\n\u003e \u003cbr/\u003e-- \u003ccite\u003e[https://en.wikipedia.org/wiki/Mutation_testing](https://en.wikipedia.org/wiki/Mutation_testing)\u003c/cite\u003e\n\nAlthough the definition states that the main purpose of mutation testing is finding implementation cases which are not covered by tests, other implementation flaws can be found too. Mutation testing can for example uncover dead and unneeded code.\n\nMutation testing is also especially interesting for comparing automatically generated test suites with manually written test suites. This was the original intention of go-mutesting which is used to evaluate the generic fuzzing and delta-debugging framework [Tavor](https://github.com/zimmski/tavor).\n\n## \u003ca name=\"how-do-i-use-go-mutesting\"\u003e\u003c/a\u003eHow do I use go-mutesting?\n\ngo-mutesting includes a binary which is go-getable.\n\n```bash\ngo install -v github.com/avito-tech/go-mutesting/...\n```\n\nThe binary's help can be invoked by executing the binary without arguments or with the `--help` argument.\n\n```bash\ngo-mutesting --help\n```\n\n\u003e **Note**: This README describes only a few of the available arguments. It is therefore advisable to examine the output of the `--help` argument.\n\nThe targets of the mutation testing can be defined as arguments to the binary. Every target can be either a Go source file, a directory or a package. Directories and packages can also include the `...` wildcard pattern which will search recursively for Go source files. Test source files with the suffix `_test` are excluded, since this would interfere with the testing process most of the time.\n\nThe following example gathers all Go files which are defined by the targets and generate mutations with all available mutators of the binary.\n\n```bash\ngo-mutesting parse.go example/ github.com/avito-tech/go-mutesting/mutator/...\n```\n\nEvery mutation has to be tested using an [exec command](#write-mutation-exec-commands). By default the built-in exec command is used, which tests a mutation using the following steps:\n\n- Replace the original file with the mutation.\n- Execute all tests of the package of the mutated file.\n- Report if the mutation was killed.\n\nAlternatively the `--exec` argument can be used to invoke an external exec command. The [/scripts/exec](/scripts/exec) directory holds basic exec commands for Go projects. The [test-mutated-package.sh](/scripts/exec/test-mutated-package.sh) script implements all steps and almost all features of the built-in exec command. It can be for example used to test the [github.com/avito-tech/go-mutesting/example](/example) package.\n\n```bash\ngo-mutesting --exec \"$GOPATH/src/github.com/avito-tech/go-mutesting/scripts/exec/test-mutated-package.sh\" github.com/avito-tech/go-mutesting/example\n```\n\nThe execution will print the following output.\n\n\u003e **Note**: This output is from an older version of go-mutesting. Up to date versions of go-mutesting will have different mutations.\n\n```diff\nPASS \"/tmp/go-mutesting-422402775//home/avito-tech/go/src/github.com/avito-tech/go-mutesting/example/example.go.0\" with checksum b705f4c99e6d572de509609eb0a625be\nPASS \"/tmp/go-mutesting-422402775//home/avito-tech/go/src/github.com/avito-tech/go-mutesting/example/example.go.1\" with checksum eb54efffc5edfc7eba2b276371b29836\nPASS \"/tmp/go-mutesting-422402775//home/avito-tech/go/src/github.com/avito-tech/go-mutesting/example/example.go.2\" with checksum 011df9567e5fee9bf75cbe5d5dc1c81f\n--- Original\n+++ New\n@@ -16,7 +16,7 @@\n        }\n\n        if n \u003c 0 {\n-               n = 0\n+\n        }\n\n        n++\nFAIL \"/tmp/go-mutesting-422402775//home/avito-tech/go/src/github.com/avito-tech/go-mutesting/example/example.go.3\" with checksum 82fc14acf7b561598bfce25bf3a162a2\nPASS \"/tmp/go-mutesting-422402775//home/avito-tech/go/src/github.com/avito-tech/go-mutesting/example/example.go.4\" with checksum 5720f1bf404abea121feb5a50caf672c\nPASS \"/tmp/go-mutesting-422402775//home/avito-tech/go/src/github.com/avito-tech/go-mutesting/example/example.go.5\" with checksum d6c1b5e25241453128f9f3bf1b9e7741\n--- Original\n+++ New\n@@ -24,7 +24,6 @@\n        n += bar()\n\n        bar()\n-       bar()\n\n        return n\n }\nFAIL \"/tmp/go-mutesting-422402775//home/avito-tech/go/src/github.com/avito-tech/go-mutesting/example/example.go.6\" with checksum 5b1ca0cfedd786d9df136a0e042df23a\nPASS \"/tmp/go-mutesting-422402775//home/avito-tech/go/src/github.com/avito-tech/go-mutesting/example/example.go.8\" with checksum 6928f4458787c7042c8b4505888300a6\nThe mutation score is 0.750000 (6 passed, 2 failed, 0 skipped, total is 8)\n```\n\nThe output shows that eight mutations have been found and tested. Six of them passed which means that the test suite failed for these mutations and the mutations were therefore killed. However, two mutations did not fail the test suite. Their source code patches are shown in the output which can be used to investigate these mutations.\n\nThe summary also shows the **mutation score** which is a metric on how many mutations are killed by the test suite and therefore states the quality of the test suite. The mutation score is calculated by dividing the number of passed mutations by the number of total mutations, for the example above this would be 6/8=0.75. A score of 1.0 means that all mutations have been killed.\n\n### \u003ca name=\"black-list-false-positives\"\u003e\u003c/a\u003eBlacklist false positives\n\nMutation testing can generate many false positives since mutation algorithms do not fully understand the given source code. `early exits` are one common example. They can be implemented as optimizations and will almost always trigger a false-positive since the unoptimized code path will be used which will lead to the same result. go-mutesting is meant to be used as an addition to automatic test suites. It is therefore necessary to mark such mutations as false-positives. This is done with the `--blacklist` argument. The argument defines a file which contains in every line a MD5 checksum of a mutation. These checksums can then be used to ignore mutations.\n\n\u003e **Note**: The blacklist feature is currently badly implemented as a change in the original source code will change all checksums.\n\nThe example output of the [How do I use go-mutesting?](#how-do-i-use-go-mutesting) section describes a mutation `example.go.6` which has the checksum `5b1ca0cfedd786d9df136a0e042df23a`. If we want to mark this mutation as a false-positive, we simple create a file with the following content.\n\n```\n5b1ca0cfedd786d9df136a0e042df23a\n```\n\nThe blacklist file, which is named `example.blacklist` in this example, can then be used to invoke go-mutesting.\n\n```bash\ngo-mutesting --blacklist example.blacklist github.com/avito-tech/go-mutesting/example\n```\n\nThe execution will print the following output.\n\n\u003e **Note**: This output is from an older version of go-mutesting. Up to date versions of go-mutesting will have different mutations.\n\n```diff\nPASS \"/tmp/go-mutesting-208240643/example.go.0\" with checksum b705f4c99e6d572de509609eb0a625be\nPASS \"/tmp/go-mutesting-208240643/example.go.1\" with checksum eb54efffc5edfc7eba2b276371b29836\nPASS \"/tmp/go-mutesting-208240643/example.go.2\" with checksum 011df9567e5fee9bf75cbe5d5dc1c81f\n--- Original\n+++ New\n@@ -16,7 +16,7 @@\n        }\n\n        if n \u003c 0 {\n-               n = 0\n+\n        }\n\n        n++\nFAIL \"/tmp/go-mutesting-208240643/example.go.3\" with checksum 82fc14acf7b561598bfce25bf3a162a2\nPASS \"/tmp/go-mutesting-208240643/example.go.4\" with checksum 5720f1bf404abea121feb5a50caf672c\nPASS \"/tmp/go-mutesting-208240643/example.go.5\" with checksum d6c1b5e25241453128f9f3bf1b9e7741\nPASS \"/tmp/go-mutesting-208240643/example.go.8\" with checksum 6928f4458787c7042c8b4505888300a6\nThe mutation score is 0.857143 (6 passed, 1 failed, 0 skipped, total is 7)\n```\n\nBy comparing this output to the original output we can state that we now have 7 mutations instead of 8.\n\n### \u003ca name=\"skip-make-args\"\u003e\u003c/a\u003eSkipping make() arguments mutation\nProblem: Useless and unwanted mutations in make() calls\n\nBefore this filter, numeric arguments in make() calls for slices/maps were mutated by incrementer/decrementer mutators, \nleading to false positives or invalid code:\n\n```bash\n// Original code\nslice := make([]int, 0)  // Capacity argument (0) was mutated\n\n// Mutated versions\nslice := make([]int, 1)  // Incrementer mutation\nslice := make([]int, -1)   // Decrementer mutation\n```\n\nThese mutations are almost always irrelevant because:\n\n1. They don't affect logical correctness\n2. Capacity/length arguments are typically well-considered\n3. Tests rarely validate exact allocation sizes\n\nThe filter prevents mutations in make() arguments.\n\n### \u003ca name=\"mutation-annotations\"\u003e\u003c/a\u003eMutation control via annotations\n\nTo further reduce false positives and provide granular control over mutations, \ngo-mutesting now supports special comment annotations. These allow you to exclude specific functions, lines, or patterns from mutation.\n\n#### Annotation Types\n1. ```bash\n   // mutator-disable-func\n   \nDisables all mutations for an entire function.  \nPlace this comment above the function declaration.\n\nExample:\n```bash\n// mutator-disable-func  \nfunc CalculateDiscount(price float64) float64 {  \n    return price * 0.9  \n}\n```\n\n2. ```bash\n   // mutator-disable-next-line \u003cmutator1\u003e, \u003cmutator2\u003e\n\nDisables mutations for the next line of code.  \nUse * to exclude all mutators.  \nSpecify mutator names (e.g., branch/case) to exclude selectively.\n\nExample:\n\n```bash\n// mutator-disable-next-line *  \nx = 42  // Fully protected from mutations  \n\n// mutator-disable-next-line branch/if, increment  \nif x \u003e 0 {  // Only branch/if and increment mutators are disabled  \n    y += 1  \n}  \n```\n\n3. ```bash\n   // mutator-disable-regexp \u003cpattern\u003e \u003cmutator1\u003e, \u003cmutator2\u003e\n\nDisables mutations for lines matching a regex pattern.  \nСan be placed on any line in the file.  \nUse * to exclude all mutators.  \nSpecify mutator names (e.g., branch/case) to exclude selectively.\n\nExample:\n```bash\ns := MyStruct{name: \"Go\"}\ns.Method()\n\n// mutator-disable-regexp s\\.Method\\(\\) *  \n```\n\nAll mutation annotations only apply to the file where they are declared. There is no global/cross-file propagation.\n\n## \u003ca name=\"write-mutation-exec-commands\"\u003e\u003c/a\u003eHow do I write my own mutation exec commands?\n\nA mutation exec command is invoked for every mutation which is necessary to test a mutation. Commands should handle at least the following phases.\n\n1. **Setup** the source to include the mutation.\n2. **Test** the source by invoking the test suite and possible other test functionality.\n3. **Cleanup** all changes and remove all temporary assets.\n4. **Report** if the mutation was killed.\n\nIt is important to note that each invocation should be isolated and therefore stateless. This means that an invocation must not interfere with other invocations.\n\nA set of environment variables, which define exactly one mutation, is passed on to the command.\n\n| Name            | Description                                                               |\n| :-------------- | :------------------------------------------------------------------------ |\n| MUTATE_CHANGED  | Defines the filename to the mutation of the original file.                |\n| MUTATE_DEBUG    | Defines if debugging output should be printed.                            |\n| MUTATE_ORIGINAL | Defines the filename to the original file which was mutated.              |\n| MUTATE_PACKAGE  | Defines the import path of the origianl file.                             |\n| MUTATE_TIMEOUT  | Defines a timeout which should be taken into account by the exec command. |\n| MUTATE_VERBOSE  | Defines if verbose output should be printed.                              |\n| TEST_RECURSIVE  | Defines if tests should be run recursively.                               |\n\nA command must exit with an appropriate exit code.\n\n| Exit code | Description                                                                                                   |\n| :------   | :--------                                                                                                     |\n| 0         | The mutation was killed. Which means that the test led to a failed test after the mutation was applied.       |\n| 1         | The mutation is alive. Which means that this could be a flaw in the test suite or even in the implementation. |\n| 2         | The mutation was skipped, since there are other problems e.g. compilation errors.                             |\n| \u003e2        | The mutation produced an unknown exit code which might be a flaw in the exec command.                         |\n\nExamples for exec commands can be found in the [scripts](/scripts/exec) directory.\n\n## \u003ca name=\"list-of-mutators\"\u003e\u003c/a\u003eWhich mutators are implemented?\n\n### Arithmetic mutators\n#### arithmetic/base\n| Name\t         | Original | Mutated |\n| :------------- | :------- | :------ |\n| Plus           | +        | -       |\n| Minus          | -        | +       |\n| Multiplication | *        | /       |\n| Division       | /        | *       |\n| Modulus        | %        | *       |\n\n#### arithmetic/bitwise\n| Name\t        | Original | Mutated |\n| :------------ | :------- | :------ |\n| BitwiseAnd    | \u0026        | \u0026#124;  |\n| BitwiseOr     | \u0026#124;   | \u0026       |\n| BitwiseXor    | ^        | \u0026       |\n| BitwiseAndNot | \u0026^       | \u0026       |\n| ShiftRight    | \\\u003e\u003e      | \u003c\u003c      |\n| ShiftLeft     | \u003c\u003c       | \\\u003e\u003e     |\n\n#### arithmetic/assign_invert\n| Name\t        | Original | Mutated |\n| :------------ | :------- | :------ |\n| AddAssign     | +=       | -=      |\n| SubAssign     | -=       | +=      |\n| MulAssign     | *=       | /=      |\n| QuoAssign     | /=       | *=      |\n| RemAssign     | %=       | *=      |\n\n#### arithmetic/assignment\n| Name\t           | Original | Mutated |\n| :--------------- | :------- | :------ |\n| AddAssignment    | +=       | =       |\n| SubAssignment    | -=       | =       |\n| MulAssignment    | *=       | =       |\n| QuoAssignment    | /=       | =       |\n| RemAssignment    | %=       | =       |\n| AndAssignment    | \u0026=       | =       |\n| OrAssignment     | \u0026#124;=  | =       |\n| XorAssignment    | ^=       | =       |\n| SHLAssignment    | \u003c\u003c=      | =       |\n| SHRAssignment    | \\\u003e\u003e=     | =       |\n| AndNotAssignment | \u0026^=      | =       |\n\n\n### Loop mutators\n#### loop/break\nName\t           | Original | Mutated  |\n| :--------------- | :------- | :------- |\n| Break            | break    | continue |\n| Continue         | continue | break    |\n\n#### loop/condition\nName\t                 | Original | Mutated  |\n| :--------------------- | :------- | :------- |\n| for k \u003c 100            | k \u003c 100  | 1 \u003c 1    |\n| for i := 0; i \u003c 5; i++ | i \u003c 5    | 1 \u003c 1    |\n\n#### loop/range_break\nIt is a loop/condition-like mutator in its purpose: removing iterations from code.  \nHowever, the implementation is slightly different. The mutator adds a break to the beginning of each range loop.\n\nName\t             | Original Body | Mutated Body |\n| :----------------- | :------------ | :----------- |\n| for i,v := range x | without break | with break   |\n\n### Numbers mutators\n#### numbers/incrementer\nName\t           | Original | Mutated  |\n| :--------------- | :------- | :------- |\n| IncrementInteger | 100      | 101      |\n| IncrementFloat   | 10.1     | 11.1     |\n\n#### numbers/decrementer\nName\t           | Original | Mutated  |\n| :--------------- | :------- | :------- |\n| DecrementInteger | 100      | 99       |\n| DecrementFloat   | 10.1     | 9.1      |\n\n### Conditional mutators\n#### conditional/negated\nName\t                          | Original | Mutated  |\n| :------------------------------ | :------- | :------- |\n| GreaterThanNegotiation          | \\\u003e       | \u003c=       |\n| LessThanNegotiation             | \u003c        | \\\u003e=      |\n| GreaterThanOrEqualToNegotiation | \\\u003e=      | \u003c        |\n| LessThanOrEqualToNegotiation    | \u003c=       | \\\u003e       |\n| Equal                           | ==       | !=       |\n| NotEqual                        | !=       | ==       |\n\nIf you are looking for simple comparison mutators - see [expression-mutators](#expression-mutators)\n\n### Branch mutators\n#### branch/case\nEmpties case bodies.\n\n#### branch/if\nEmpties branches of `if` and `else if` statements.\n\n#### branch/else\nEmpties branches of `else` statements.\n\n### Expression mutators\n#### expression/comparison\nSearches for comparison operators, such as `\u003e` and `\u003c=`, and replaces them with similar operators to catch off-by-one errors, e.g. `\u003e` is replaced by `\u003e=`.\n\nName\t               | Original | Mutated  |\n| :------------------- | :------- | :------- |\n| GreaterThan          | \\\u003e       | \\\u003e=      |\n| LessThan             | \u003c        | \u003c=       |\n| GreaterThanOrEqualTo | \\\u003e=      | \\\u003e       |\n| LessThanOrEqualTo    | \u003c=       | \u003c        |\n\n#### expression/remove\nSearches for `\u0026\u0026` and \u003ccode\u003e\\|\\|\u003c/code\u003e operators and makes each term of the operator irrelevant by using `true` or `false` as replacements.\n\n### Statement mutators\n#### statement/remove\nRemoves assignment, increment, decrement and expression statements.\n\n## Config file\n\nThere is a configuration file where you can fine-tune mutation testing.  \nThe config must be written in YAML format.  \nIf `--config` is presented, the library will use the given config. Otherwise, no default config file will be used.  \nThe config contains the following parameters:  \n\n\n| Name                 | Default value | Description                                                                                                                                                        |\n|:---------------------| :------------ |:-------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| skip_without_test    | true          | Skip files without _test.go tests.                                                                                                                                 |\n| skip_with_build_tags | true          | If in _test.go file we have --build tag - then skip it.                                                                                                            |\n| json_output          | false         | Make report.json file with a mutation test report.                                                                                                                 |\n| html_output          | false         | Make go-mutesting-report.html file with a mutation test report.                                                                                                    |\n| silent_mode          | false         | Do not print mutation stats.                                                                                                                                       |\n| exclude_dirs         | []string(nil) | Directories for excluding. In fact, there are not directories. These are the prefix for a path when we scan a file system. So this parameter is sensitive for args |\n\n## \u003ca name=\"write-mutators\"\u003e\u003c/a\u003eHow do I write my own mutators?\n\nEach mutator must implement the `Mutator` interface of the [github.com/avito-tech/go-mutesting/mutator](https://godoc.org/github.com/avito-tech/go-mutesting/mutator#Mutator) package. The methods of the interface are described in detail in the source code documentation.\n\nAdditionally each mutator has to be registered with the `Register` function of the [github.com/avito-tech/go-mutesting/mutator](https://godoc.org/github.com/avito-tech/go-mutesting/mutator#Mutator) package to make it usable by the binary.\n\nExamples for mutators can be found in the [github.com/avito-tech/go-mutesting/mutator](https://godoc.org/github.com/avito-tech/go-mutesting/mutator) package and its sub-packages.\n\n## \u003ca name=\"other-projects\"\u003e\u003c/a\u003eOther mutation testing projects and their flaws\n\ngo-mutesting is not the first project to implement mutation testing for Go source code. A quick search uncovers the following projects.\n\n- https://github.com/darkhelmet/manbearpig\n- https://github.com/kisielk/mutator\n- https://github.com/StefanSchroeder/Golang-Mutation-testing\n\nAll of them have significant flaws in comparison to go-mutesting:\n\n- Only one type (or even one case) of mutation is implemented.\n- Can only be used for one mutator at a time (manbearpig, Golang-Mutation-testing).\n- Mutation is done by content which can lead to lots of invalid mutations (Golang-Mutation-testing).\n- New mutators are not easily implemented and integrated.\n- Can only be used for one package or file at a time.\n- Other scenarios as `go test` cannot be applied.\n- Do not properly clean up or handle fatal failures.\n- No automatic tests to ensure that the algorithms are working at all.\n- Uses another language (Golang-Mutation-testing).\n\n## \u003ca name=\"feature-request\"\u003e\u003c/a\u003eCan I make feature requests and report bugs and problems?\n\nSure, just submit an [issue via the project tracker](https://github.com/avito-tech/go-mutesting/issues/new) and we will see what I can do.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Favito-tech%2Fgo-mutesting","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Favito-tech%2Fgo-mutesting","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Favito-tech%2Fgo-mutesting/lists"}