Cosmic Ray Documentation
repository·master·Indexed 20 days ago
https://github.com/sixty-north/cosmic-rayA mutation testing tool for Python 3 that evaluates test suite effectiveness by injecting small changes into source code and running tests to see if they fail. It utilizes AST manipulation via parso to create mutants and supports various distributors, such as LocalDistributor and HttpDistributor, to execute tests. The tool includes a system for sessions, TOML-based configuration, and filters like cr-filter-operators, cr-filter-pragma, and cr-filter-git to refine mutation scope.
What's inside Cosmic Ray
- Cosmic Ray is a mutation testing tool designed for Python 3. It works by injecting small, controlled changes (mutations) into your source code and then running your existing test suite against each version. This process helps you evaluate the effectiveness of your tests by determining if they can detect the changes made to the code.
What is Cosmic Ray mutation testing?
masterCosmic Ray is a mutation testing tool for Python 3. It works by making small, automated changes (mutations) to your production source code and then running your existing test suite against each mutated version.
Key distinction from coverage analysis:
- Coverage analysis tells you if a line of code was executed during tests.
- Mutation testing determines if your tests actually validate the behavior of that code.
If your test suite passes even after the code has been mutated, it indicates a 'survived mutant,' meaning your tests are not effectively checking that specific functionality.
Overview of the cosmic_ray.operators package
masterThecosmic_ray.operatorspackage contains the core mutation logic for Cosmic Ray. Operators are responsible for defining how code is transformed to create mutants. The package is organized into specialized submodules, each handling a specific type of code mutation (e.g., replacing boolean values, changing comparison operators, or removing decorators).What is mutation testing and how does it work?
masterMutation testing is a technique used to verify the effectiveness of your test suite. It works by making controlled, intentional changes (mutations) to your code under test. You then run your existing test suite against this mutated code to see if your tests can detect the changes.
There are three primary outcomes for a mutant:
- Killed: Your test suite fails when run against the mutated code. This is the desired outcome, as it means your tests successfully detected the incorrect behavior.
- Survived: Your test suite passes despite the mutation. This indicates that your tests are not adequately checking the specific logic that was changed.
- Incompetent: The mutation causes the code to crash (e.g., a syntax error or a fatal runtime error) rather than just changing the logic.
The ultimate goal is to maximize the number of 'killed' mutants. A surviving mutant suggests you either need to write better/more tests or remove the unnecessary code that the mutation affected.
How Cosmic Ray performs mutation testing
masterCosmic Ray implements mutation testing by manipulating the Abstract Syntax Trees (AST) of the Module Under Test (MUT) and its submodules.
- Parsing: It uses
parsoto parse the source code into ASTs. - Mutation: Mutation operators walk these trees to modify or delete specific nodes.
- Code Generation: The modified ASTs are converted back into source code and written to disk.
- Execution: Cosmic Ray runs user-supplied test commands against the mutated code on disk.
Outcomes of a mutation run:
- Mutant Survived: The tests passed despite the mutation (the mutation was not caught).
- Mutant Killed: The tests failed as expected due to the mutation.
- Mutant Incompetent: An exception occurred during the test run (e.g., a syntax error or runtime error caused by the mutation itself).
for mod in modules_under_test: for op in mutation_operators: for site in mutation_sites(op, mod): mutant_ast = mutate_ast(op, mod, site) write_to_disk(mutant_ast) try: if discover_and_run_tests(): print('Oh no! The mutant survived!') else: print('The mutant was killed.') except Exception: print('The mutant was incompetent.')- Parsing: It uses
Best practices for separating test and production code
masterCosmic Ray attempts to mutate all code within a specified module. If test code resides in the same module as production code, Cosmic Ray will mutate the tests, which is usually undesirable.
Recommendations:
- Separate Modules: Keep test code in separate modules from production code. This allows you to target only production code for mutation.
- Separate Packages: Ideally, keep tests in a different package entirely. This allows you to mutate an entire package without filtering.
- Use
excluded-modules: If tests must reside in the same package, use theexcluded-modulessetting in yourconfig.tomlto prevent Cosmic Ray from mutating them.
What are Sessions and how to initialize them
masterA session is a database (typically a
.sqlitefile) that records the work to be done and the results returned by workers. Sessions allow Cosmic Ray to be interrupted and restarted safely, as the database tracks completed work. They also enable post-facto analysis and report generation.To initialize a session, use the
initcommand, specifying a configuration file and a session name (which becomes the database filename).cosmic-ray init config.toml session.sqliteRun reporting commands concurrently with execution
masterMost Cosmic Ray commands can be safely executed while a mutation testing session is currently running via
exec. This allows you to monitor progress in real-time.Exception: Do not run
initwhileexecis running, asinitrewrites the work manifest and may cause conflicts.What are Operators in Cosmic Ray
masterAn operator is a class that represents a specific type of mutation. It has two primary roles:
- Identification: It finds points in the code where a specific mutation can be applied.
- Execution: It performs the mutation (e.g., replacing a
breaknode with acontinuenode).
Operators are implemented as subclasses of
cosmic_ray.operators.operator.Operatorand are exposed via plugins. Users can extend the available set by providing their own operators.from cosmic_ray.operators.operator import Operator class MyCustomOperator(Operator): # Implementation details for identifying and applying mutations passHow the HTTP distributor works for distributed mutation testing
masterThe
cosmic_ray.distributors.http.HttpDistributorallows you to parallelize mutation testing by sending requests to one or more workers running locally or remotely.Key Concepts:
- Workers: Each worker is a small HTTP server that handles one mutation request at a time.
- Isolation: Each worker must have its own independent copy of the code under test. Because Cosmic Ray modifies code on disk to perform mutations, workers cannot share the same directory without interfering with each other.
- Execution Flow: You must start your workers before running the
execcommand. Theexeccommand does not start workers automatically; it only communicates with the endpoints provided in your configuration.
What are Distributors in Cosmic Ray
masterDistributors determine the execution context for tests. They are implemented as plugins and are responsible for taking a sequence of pending mutations and executing them in the appropriate environment.
Common distributors include:
LocalDistributor: Runs tests on the local machine, modifying code in-place and running tests serially (no concurrency).HttpDistributor: Distributes tests to remote workers via HTTP. This allows for parallel execution, where each worker typically maintains its own copy of the code under test.
Distributors can require specific infrastructure; for example, the
HttpDistributorrequires workers to be started prior to execution and requires each worker to have its own copy of the code.Understanding development versions
masterCosmic Ray uses dynamic VCS-based versioning via
hatch-vcs/setuptools-scm.Any build created outside of an official
release/vX.Y.Ztag will be identified as a development version. These versions follow a pattern such as8.5.1.dev3+g<hash>, making it clear that the build is not a final release.