6.1. ats_linter package
6.1.1. Submodules
6.1.2. ats_linter.ast_test_module_factory module
Copyright (c) 2023 Aydin Abdi.
ASTTestModuleFactory is a factory class for creating test modules based on Python’s AST (Abstract Syntax Tree). It encapsulates the logic of parsing an AST from a Python test file, extracting test module, classes, cases, and pytest fixtures. Test cases are based on unittest.TestCase and pytest test functions and fixtures based on pytest fixtures.
- class ats_linter.ast_test_module_factory.ASTTestModuleFactory[source]
Bases:
objectTest module factory based on Python’s AST (Abstract Syntax Tree).
This class encapsulates the logic of parsing an AST from a Python test file, extracting test module, classes, cases, and pytest fixtures. Test cases are based on unittest.TestCase and pytest test functions and fixtures based on pytest fixtures.
- static extract_entities(nodes: list[AST], entity_class: Entity, condition: Callable[[AST], bool]) Sequence[Entity][source]
Extract entities of a given type from the list of nodes.
- Parameters:
nodes – A list of AST nodes to extract entities from.
entity_class – The class of the entity to extract.
condition – A function that defines the condition for entity extraction.
- Returns:
A list of entity instances extracted from the nodes.
- static get_function_nodes(nodes: list[AST]) list[FunctionDef][source]
Get function nodes from a list of AST nodes.
- Parameters:
nodes – The list of AST nodes.
- Returns:
The function nodes from the list of nodes.
- static get_test_classes(nodes: list[AST]) list[ClassDef][source]
Get test classes from a list of AST nodes.
- Parameters:
nodes – The list of AST nodes.
- Returns:
The test classes from the list of nodes.
- static is_pytest_fixture(node: AST) bool[source]
Check if a node is a pytest fixture.
- Parameters:
node – The node to check.
- Returns:
Boolean value indicating whether the node is a pytest fixture.
6.1.3. ats_linter.async_ast_parser module
Copyright (c) 2023 Aydin Abdi.
ASTProducer reads files and produces AST(Abstract Syntax Tree)s.
- class ats_linter.async_ast_parser.ASTConsumer(ast_tree_queue: Queue, test_modules: list[TestModule])[source]
Bases:
objectParse ASTs into TestModule objects.
This class encapsulates the logic of parsing ASTs into TestModule objects. The ASTs are consumed asynchronously from a queue.
- Parameters:
ast_tree_queue (The queue of ASTs produced from the Python files.)
test_modules (The queue of TestModule objects produced from the ASTs.)
task (The asyncio task that consumes the ASTs.)
- ast_tree_queue: Queue
- async consume_ast_trees() None[source]
Consume ASTs from the queue and parse them into TestModule objects.
This method consumes ASTs from the queue and parses them into TestModule objects. The method will stop consuming ASTs when it encounters the sentinel value.
- parse_ast_tree(module_name: Path, ast_tree: Module) TestModule[source]
Parse an AST into a TestModule object.
- Parameters:
module_name – Path to the module.
ast_tree – The AST of the module.
- Returns:
class: TestModule object.
- Return type:
The
- test_modules: list[TestModule]
- class ats_linter.async_ast_parser.ASTProducer(file_paths: list[~pathlib.Path], ast_tree_queue: ~asyncio.queues.Queue = <factory>)[source]
Bases:
objectRead files and produce AST(Abstract Syntax Tree)s.
This class encapsulates the logic of reading Python files and producing ASTs. The ASTs are produced asynchronously and put in a queue.
- Parameters:
file_paths (The list of :class: Path objects of the Python files to parse.)
ast_tree_queue (The queue of ASTs produced from the Python files.)
task (The asyncio task that produces the ASTs.)
- ast_tree_queue: Queue
- static is_test_file(file_path: Path) bool[source]
Check if file is a test module.
- Parameters:
file_path – The path of the file to check.
- Returns:
Boolean value indicating whether the file is a test module.
- class ats_linter.async_ast_parser.AsyncASTParser(file_paths: list[~pathlib.Path], test_modules: list[~ats_linter.data_classes.TestModule] = <factory>)[source]
Bases:
objectParse Python files into TestModule objects.
This class encapsulates the logic of parsing Python files into TestModule objects. It is used in conjunction with ASTProducer and ASTConsumer.
- Parameters:
file_paths (The paths of the Python files to parse.)
test_modules (The list of TestModule objects produced from the Python files.)
- test_modules: list[TestModule]
6.1.4. ats_linter.cli module
Copyright (c) 2023 Aydin Abdi.
CLI for the Automated Test Schema Linter (ATS Linter). Modern, typed, and Pythonic using Typer.
- ats_linter.cli.main(files: ~typing.Annotated[list[str], <typer.models.ArgumentInfo object at 0x78f0250895d0>] = None, debug: ~typing.Annotated[bool, <typer.models.OptionInfo object at 0x78f022fbae50>] = False) None[source]
Lint test files for docstring compliance.
- Parameters:
files – Files or directories to lint (default: tests/ directory)
debug – Enable debug logging
6.1.5. ats_linter.data_classes module
Copyright (c) 2023 Aydin Abdi.
This module defines the data classes used in this module.
- class ats_linter.data_classes.Entity(name: str, docstring: str | None, code: str)[source]
Bases:
objectRepresent a generic entity in a test module.
- Parameters:
name (The name of the entity.)
docstring (The docstring of the entity.)
code (The code of the entity.)
- class ats_linter.data_classes.PytestFixture(name: str, docstring: str | None, code: str)[source]
Bases:
objectRepresent a pytest fixture.
- Parameters:
name (The name of the fixture.)
docstring (The docstring of the fixture.)
code (The code of the fixture.)
- class ats_linter.data_classes.Section(name: str, error_message: str | None)[source]
Bases:
objectRepresent a section in a test description for MHSTestLinter.
- Parameters:
name (The name of the section.)
error_message (The error message of the section.)
- class ats_linter.data_classes.TestCase(name: str, docstring: str, code: str)[source]
Bases:
objectRepresent a test case.
- Parameters:
name (The name of the test case.)
docstring (The docstring of the test case.)
code (The code of the test case.)
- class ats_linter.data_classes.TestClass(name: str, docstring: str | None, test_cases: list[TestCase], fixtures: list[PytestFixture])[source]
Bases:
objectRepresent a test class.
- Parameters:
name (The name of the test class.)
docstring (The docstring of the test class.)
test_cases (The list of test cases in the class.)
fixtures (The list of fixtures in the class.)
- fixtures: list[PytestFixture]
- class ats_linter.data_classes.TestModule(name: str, test_classes: list[TestClass], test_cases: list[TestCase], fixtures: list[PytestFixture])[source]
Bases:
objectRepresent a test module.
- Parameters:
name (The name of the module.)
test_classes (The list of test classes in the module.)
test_cases (The list of test cases in the module.)
fixtures (The list of fixtures in the module.)
- fixtures: list[PytestFixture]
6.1.6. ats_linter.description module
Copyright (c) 2023 Aydin Abdi.
This module encapsulates the logic of parsing test case test descriptions.
- class ats_linter.description.TestDescription(docstring: str, objective: str | None = None, approvals: list[str] = <factory>, preconditions: dict[int, str] | None=<factory>, data_driven_test: list[str] | None = <factory>, test_steps: dict[int, str]=<factory>, verify_steps: dict[int, str]=<factory>)[source]
Bases:
objectRepresents a test case test description.
- Parameters:
objective (The objective of the test.)
approvals (The approval criteria of the test.)
preconditions (The preconditions of the test. None if not provided.)
data_driven_test (The data-driven test descriptions. None if not provided.)
test_steps (The steps to execute the test.)
verify_steps (The steps that verifies test.)
- class ats_linter.description.TestDescriptionFactory[source]
Bases:
objectCreate a TestDescription instance from various sources.
- static dataclass_test_docstring_factory(docstring: str) TestDescription[source]
Create a TestDescription instance from a docstring.
- Parameters:
docstring – The docstring to parse.
- Returns:
class: TestDescription instance.
- static from_docstring(docstring: str) TestDescription[source]
Create a TestDescription from a docstring (compatibility alias).
- static parse_dash_list_section(section: str) list[str][source]
Parse dash(start with ‘-’) list sections from the docstring.
- Parameters:
section – The section string to parse.
- Returns:
A list of items parsed from the section.
6.1.7. ats_linter.exception module
Copyright (c) 2023 Aydin Abdi.
This module defines the base class for exceptions in this module.
Example
raise ATSLinterError(“This is an error message.”)
- exception ats_linter.exception.ATSASTParseError(message: str)[source]
Bases:
ATSLinterErrorException raised for errors in AST parsing.
- exception ats_linter.exception.ATSFileCollectionError(message: str)[source]
Bases:
ATSLinterErrorException raised for errors in file collection.
6.1.8. ats_linter.file_collector module
Copyright (c) 2023 Aydin Abdi.
This module defines a class for collecting test directories and files.
Example
test_directory = FileCollector(‘/path/to/root/directory’) print(test_directory.test_directories) print(test_directory.test_files)
- class ats_linter.file_collector.FileCollector(root_file_path: dataclasses.InitVar[str])[source]
Bases:
objectCollect test directories and files from a root directory or file.
- Parameters:
root_file_path (The path of the root directory or file.)
root_path (The root directory as a Path object.)
test_directories (A list of all directories that contain test files.)
test_files (A list of all test files.)
Example
test_directory = FileCollector(‘/path/to/root/directory’) print(test_directory.test_directories) print(test_directory.test_files)
- collect_test_directories_and_files_in_parallel() None[source]
Collect all test directories and files in parallel.
If the root directory is a file, simply add it to the test files and return. If the root directory is a directory, collect all test directories and files.
- static get_path_from_string(file_path: str) Path[source]
Return a Path object for a given file path string.
- Parameters:
file_path – The file path as a string.
- Returns:
The file path as a Path object.
- static is_test_directory(directory: Path) bool[source]
Check if the directory is a test directory.
A directory is considered a test directory if it starts with
testortest_ortestsand contains at least one file that starts withtest_.- Parameters:
directory – The directory to check.
- Returns:
True if the directory is a test directory, False otherwise.
- static is_test_file(file: Path) bool[source]
Check if the file is a test file.
- Parameters:
file – The file to check.
- Returns:
True if the file is a test file, False otherwise.
6.1.9. ats_linter.linter module
Copyright (c) 2023 Aydin Abdi.
Module to lint test files.
This module provides a class to lint test files.
- class ats_linter.linter.ATSTestCase(test_case: TestCase)[source]
Bases:
objectRepresents a ATS test case.
- Parameters:
test_case (The test case.)
test_description (ATS test case description :class: TestDescription.)
- test_description: TestDescription = None
- class ats_linter.linter.ATSTestCasesFactory(test_cases: list[TestCase])[source]
Bases:
objectFactory class to create :class: ATSTestCase objects.
- Parameters:
test_cases (The list of :class: TestCase objects.)
ats_test_cases (The list of :class: ATSTestCase objects.)
- ats_test_cases: list[ATSTestCase]
- class ats_linter.linter.ATSTestCasesLinter(ats_test_cases: list[ATSTestCase])[source]
Bases:
objectClass to lint multiple ATS test cases.
- Parameters:
ats_test_cases (The list of ATS test cases to lint.)
Example – (Doctest temporarily disabled due to API complexity) # >>> from ats_linter.data_classes import TestCase # >>> from ats_linter.linter import ATSTestCasesFactory, ATSTestCasesLinter # >>> test_case_1 = TestCase( # … name=”Test case name 1”, # … docstring=”Test case description 1”, # … code=”def test_something_1(): pass”, # … ) # >>> test_case_2 = TestCase( # … name=”Test case name 2”, # … docstring=”Test case description 2”, # … code=”def test_something_2(): pass”, # … ) # >>> factory = ATSTestCasesFactory([test_case_1, test_case_2]) # >>> ats_test_cases_linter = ATSTestCasesLinter(factory.ats_test_cases) # >>> ats_test_cases_linter.lint()
- ats_test_cases: list[ATSTestCase]
- class ats_linter.linter.LintResult(module_name: str, class_name: str, test_name: str, sections: list[Section], result: bool)[source]
Bases:
objectClass to represent the result of linting a test case.
- class ats_linter.linter.LintTestCase(ats_test_case: ATSTestCase)[source]
Bases:
objectClass to lint ATS test cases.
- Parameters:
ats_test_case (The ATS test case :class: ATSTestCase.)
test_case (The test case :class: TestCase to lint.)
test_description (The ATS test case description :class: TestDescription.)
sections (The list of sections in the test case.)
Example – (Doctest temporarily disabled due to API complexity) # >>> from ats_linter.data_classes import TestCase # >>> from ats_linter.linter import ATSTestCase, LintTestCase # >>> test_case = TestCase( # … name=”Test case name”, # … docstring=”Test case description”, # … code=”def test_something(): pass”, # … ) # >>> ats_test_case = ATSTestCase(test_case) # >>> test_case_linter = LintTestCase(ats_test_case) # >>> test_case_linter.lint() # >>> test_case_linter.sections
- ats_test_case: ATSTestCase
- lint() bool[source]
Lint the test case docstring and return the linting result.
- Returns:
True if the test case docstring passes linting, False otherwise.
- lint_result: LintResult
- test_description: TestDescription
- ats_linter.linter.lint_ats_test_case(ats_test_case: ATSTestCase, lint_results: dict[str, Any], lock: allocate_lock) bool[source]
Lint a single test case.
- Parameters:
ats_test_case – The ATS test case to lint.
lint_results – The dictionary to store linting results.
lock – The lock to ensure thread-safe access to the results dictionary.
- Returns:
True if the test case passes linting, False otherwise.
6.1.10. ats_linter.parallel_process module
Copyright (c) 2023 Aydin Abdi.
FileProcessorCocurrent is a class for processing files in parallel.
- class ats_linter.parallel_process.FileProcessorCocurrent(root_path: str)[source]
Bases:
objectA class for processing files in parallel.
- async_ast_parser: AsyncASTParser
- test_file_collector: FileCollector
6.1.11. Module contents
Copyright (c) 2023 Aydin Abdi
Ats-linter(Automated Test Schema Linter) is a package for linting test files. It is a tool that checks the validity of test case docstrings and test code based on the defined schema. It is designed to be used in a CI/CD pipeline to ensure that test cases are written according to the defined schema. It is also designed to be used as a standalone tool to lint test files locally. It is built on top of Python’s AST (Abstract Syntax Tree). It can be used as a pre-commit hook.
Example
To lint test files locally, run the following command:
$ ats-linter --path tests/
To lint test files in a CI/CD pipeline, run the following command:
$ ats-linter --path tests/ --output junit.xml
The junit.xml file can be used to generate a report in Jenkins.
To lint test files in a CI/CD pipeline, run the following command:
$ ats-linter --path tests/ --output junit.xml
The junit.xml file can be used to generate a report in Jenkins.