How to Run the Test Suite and Contribute to GPT-Academic: A Complete Guide
You can run the GPT-Academic test suite by installing dependencies from requirements.txt and executing pytest -q from the repository root, while contributions follow a standard fork-branch-test-PR workflow using the plugin_test helper for validation.
GPT-Academic (binary-husky/gpt_academic) ships a pytest-based test suite that validates core utilities, the plugin system, and optional LLM back-ends. Whether you are fixing a bug or adding a new function plugin to the crazy_functions/ directory, running the test suite locally ensures your changes do not break existing functionality. This guide covers the exact commands, file structures, and contribution standards used in the upstream repository.
Understanding the GPT-Academic Test Architecture
The testing framework is tightly coupled with the toolbox (toolbox.py) and the plugin harness defined in crazy_functions/. Understanding these components helps you write effective tests and debug failures faster.
Core Testing Components
| Component | Role | Source Location |
|---|---|---|
| pytest | Test runner discovering files prefixed with test_ inside tests/. |
requirements.txt |
| tests/ | Directory containing unit-style tests (test_utils.py, test_vector_plugins.py) that exercise configuration loading and plugin behaviors. |
tests/ |
| tests/test_utils.py | Provides the plugin_test helper which creates a void terminal (VoidTerminal) to silence UI output and invoke plugins deterministically. |
tests/test_utils.py |
| toolbox.py | Core helper functions (get_conf, get_plugin_handle, get_plugin_default_kwargs) used by both the application and test harness. |
toolbox.py |
| crazy_functions/ | Modular function plugins (e.g., Vectorstore_QA, PDF_Translate) imported directly by tests. |
crazy_functions/ |
The VoidTerminal Pattern
When testing plugins that normally interact with the UI, the suite uses a mock terminal class to suppress stdout and capture errors. In tests/test_utils.py, the plugin_test function instantiates VoidTerminal to isolate plugin execution from the Gradio interface, allowing deterministic validation of business logic without rendering UI elements.
How to Run the Test Suite Locally
Follow these steps to execute the full suite or target specific components during development.
-
Install the project dependencies from the repository root. The
requirements.txtincludespytestand all necessary libraries.pip install -r requirements.txt -
Navigate to the repository root to ensure
sys.pathresolves correctly (theinit_test.pyscript adjusts paths accordingly).cd path/to/gpt_academic -
Run the entire suite with quiet output for a quick pass/fail summary.
pytest -q -
Run a specific test file when developing a particular plugin category.
pytest -vv tests/test_vector_plugins.py -
Run a single test function using the
::separator to isolate failures during debugging.pytest tests/test_utils.py::test_plugin_load -
Optional: Use a virtual environment (
venv,conda, oruv) to keep dependencies isolated. The repositoryDockerfilealso defines a container that runspytestreproducibly.
Contributing Code to GPT-Academic
Contributions follow a standard GitHub workflow enforced by CI pipelines in .github/workflows/.
Setting Up Your Development Environment
Before writing code, fork the repository and install dependencies locally. The test suite must pass on your machine before opening a Pull Request, as the same pytest -q command runs automatically in GitHub Actions on every push.
The Contribution Workflow
| Step | Action | Command / Details |
|---|---|---|
| 1. Fork | Create your own copy on GitHub. | Use the GitHub web interface. |
| 2. Clone | Pull the fork locally. | git clone https://github.com/<your-user>/gpt_academic.git |
| 3. Branch | Use descriptive names like feature/markdown-translator. |
git checkout -b feature/markdown-translator |
| 4. Install | Same dependencies as production. | pip install -r requirements.txt |
| 5. Code | Implement features while keeping the plugin API consistent. | Respect get_plugin_handle and get_plugin_default_kwargs signatures. |
| 6. Test | Add or extend pytest files under tests/. |
Reuse the plugin_test helper. |
| 7. Validate | Ensure no regressions. | pytest -q |
| 8. Commit | Reference issue numbers when applicable. | git commit -m "feat: add markdown translator (#123)" |
| 9. Push | Upload your branch. | git push origin feature/markdown-translator |
| 10. Pull Request | Submit against binary-husky/gpt_academic:master. |
CI runs automatically; address failures promptly. |
When modifying core behavior in toolbox.py or the plugin loader, update the documentation (e.g., docs/README.English.md) and add test cases demonstrating the new behavior.
Writing Tests for Custom Plugins
New plugins in crazy_functions/ require tests that verify initialization and execution without triggering the full UI. Use the plugin_test utility from tests/test_utils.py to invoke your plugin through the same pathway the application uses.
Example: Testing a New Plugin
Create a file tests/test_my_plugin.py following this pattern:
from tests.test_utils import plugin_test
def test_my_new_plugin():
plugin_test(
plugin="crazy_functions.MyNewPlugin->描述功能",
main_input="some input data",
advanced_arg={"extra": "value"},
debug=False # silences verbose UI output
)
Run the specific test to validate your implementation:
pytest tests/test_my_plugin.py -v
The plugin_test function automatically invokes your plugin inside the void terminal and asserts that it finishes without raising exceptions, ensuring compatibility with the broader system.
Summary
- Install dependencies using
pip install -r requirements.txtto obtain pytest and all required packages. - Run the full suite with
pytest -qfrom the repository root to validate changes locally. - Target specific tests using
pytest path/to/file.py::function_namefor rapid iteration during development. - Use
plugin_testfromtests/test_utils.pyto exercise plugins in isolation via theVoidTerminalpattern. - Follow the fork-branch-test-PR workflow and ensure CI passes in
.github/workflows/before requesting review. - Update tests and documentation when modifying core utilities in
toolbox.pyor thecrazy_functions/plugin API.
Frequently Asked Questions
What dependencies do I need to run tests?
You only need to install the packages listed in requirements.txt at the repository root. This file includes pytest and all libraries required by the core application and plugins. No separate requirements-dev.txt exists; production and test dependencies are unified.
How do I test a single plugin without running the full suite?
Use the plugin_test helper imported from tests/test_utils.py. Pass your plugin string (e.g., "crazy_functions.PDF_Translate->批量翻译PDF文档") and sample inputs to execute just that logic within a void terminal context. This approach is faster than loading the entire Gradio interface.
What is the VoidTerminal class and why is it used?
VoidTerminal is a mock terminal class defined in tests/test_utils.py that silences UI output and captures stdout during plugin execution. It allows pytest to run plugins deterministically without spawning the actual Gradio web interface, making CI runs faster and tests more reliable.
How does the CI ensure contributions don't break the project?
GitHub Actions workflows in .github/workflows/ execute pytest automatically on every push and pull request against the master branch. If your changes cause any test in tests/ to fail, the PR checks will block merging until you fix the regression or update the affected test cases to reflect intended behavioral changes.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →