How does pytest runner interact with TeamCity
Hi all,
I was looking at the file `_jb_pytest_runner.py` that PyCharm runs when using a Pytest run configuration.
I see that it loads the `pytest-teamcity` plugin, which contains the `pytest_plugin` file. Here's a link to the file I'm referring to:
I was curious how it interacts with TeamCity (and how it spins up an instance of TeamCity if necessary). Further, I was curious how pytest output goes through TeamCity and then eventually ends up in the “Run” output of PyCharm.
Also, would the TeamCity Server instance show up in Task Manager on Windows?
Unsure if this is the best place to ask this question, let me know if it's not!
Thank you!
请先登录再写评论。
Hi,
Thank you for reaching out!
> 1. Does it spin up a TeamCity instance?
No. PyCharm does not start or embed a TeamCity server.
In this context, “TeamCity” refers to the TeamCity Service Message protocol, which is a lightweight, text-based reporting format developed by JetBrains. It allows tools like test runners to report structured information (test start, failure, duration, etc.) by printing specially formatted strings to stdout.
> How the Interaction Works
The pytest_plugin.py file you referenced acts as a translator layer:
- It hooks into the Pytest lifecycle (test started, failed, finished, etc.).
- For each event, it prints a TeamCity service message to stdout.
For example, when Pytest finishes collecting tests, you’ll see output like
These messages are plain text, but they follow a strict format that tooling can recognize.
3. How Output Reaches the PyCharm "Run" Window
Here’s the full data flow:
Execution
Pytest runs the tests as a normal Python process.
Transformation
The pytest-teamcity plugin converts Pytest events (start, fail, error, finish) into TeamCity service messages.
Stdout
These messages are written to standard output, mixed in with normal console output.
Parsing
PyCharm’s IDE process monitors the stdout stream and parses lines starting with:
Relationship to an actual TeamCity server:
If you later run the same tests in a real TeamCity build (for example, using the Python runner with pytest --teamcity), the flow is identical:
- Pytest emits TeamCity service messages
- TeamCity parses them
- Test results appear in the TeamCity UI
This shared protocol is what allows:
- Local execution in PyCharm
- CI execution in TeamCity
Summary
- PyCharm does not start or require a TeamCity server.
- The integration is based entirely on TeamCity Service Messages written to stdout.
- pytest-teamcity converts Pytest events into those messages.
- PyCharm parses and renders them in the Run tool window.
- The same mechanism is used by the TeamCity server in CI environments.
Below is a minimal demo project you can use to observe how Pytest integrates with PyCharm and TeamCity service messages.
pydemo/
Step 1: Initialize the Project in PyCharm
1. Open PyCharm and create a New Project.
2. Select Python Interpreter → New Virtualenv.
3. Create the following files and directories (right-click project root → New → File):
Step 2: Configure Pytest as the Default Test Runner
Step 3: Add Sample Code and Tests
src/math_logic.py
tests/test_math.py
pyproject.toml
requirements.txt
Step 4: Running Tests with TeamCity Service Messages
If you run the tests locally using:
You will see TeamCity service messages in the output, for example:
collected 2 items
Followed by messages such as testStarted, testFailed, and testFinished, which encode structured test information in stdout. These are the same messages parsed by PyCharm and the TeamCity server.
Step 5: Running the Same Tests in TeamCity
1. To run this project in TeamCity:
2. Commit the code to your repository.
3. Create a TeamCity project and a Build Configuration.
4. Add a Python Runner build step.
5. Configure it to run pytest - Enable test reporting via teamcity-messages (https://pypi.python.org/pypi/teamcity-messages)
6. Run the build.
The test results will be parsed from the service messages and displayed in the TeamCity Tests tab, just as they are rendered in PyCharm locally.
Tom Sun,
Thank you for your reply! This is great information thank you.
As a follow-up, I did want to ask something regarding this step in the process:
Is this portion of the process open source and part of the `intellij-community` repository? Or is it perhaps somewhere else?
Thanks so much again.
Hi,
You are very welcome!
> Is this portion of the process open source and part of the `intellij-community` repository? Or is it perhaps somewhere else?
No, the interaction between Service Messages and the IDE can be a bit nuanced until you see it in action, if you run the tests locally with terminal console using:
To wrap up, you've got it exactly right:
- Locally: pytest --teamcity allows PyCharm to intercept those ##teamcity[...] service message and render them in the UI.
- On TeamCity: The Python runner handles these same messages to populate the build test results.
In TeamCity, you can easily set up a build configuration and add a Python runner step. This will allow TeamCity to capture those ##teamcity[...] service messages and display your test results.
Tom Sun,
Thank you for all of the info and screenshots, this is very helpful to reproduce the steps on how the #teamcity messages are produced! You mentioned:
Just to be clear, are either the TeamCity code or the PyCharm code that parses the #teamcity messages open source? To be clear I'm referring to the final output in the “Run” window in PyCharm or the “Tests” tab in TeamCity.
Hi,
> are either the TeamCity code or the PyCharm code that parses the #teamcity messages open source?
To answer your question directly: yes and no, depending on which part of the pipeline you are referring to.
PyCharm side
The code responsible for emitting and parsing #teamcity service messages in PyCharm (including the pytest integration you mentioned) is open source.
For example, the pytest-teamcity plugin and the related helper scripts used by PyCharm are part of the IntelliJ / PyCharm open-source repositories, and you can inspect how test events are translated into #teamcity messages there.
TeamCity side
The core TeamCity server logic that parses #teamcity service messages and renders them in the Tests tab is not open source. This functionality is implemented as part of the proprietary TeamCity server and agent code.
In summary:
- Emission and client-side parsing of #teamcity messages in PyCharm: open source
- Server-side parsing and UI rendering in TeamCity (Tests tab, build results): closed source
That said, the TeamCity Service Message specification itself is public, and its format and behavior are well documented. This allows external tools and test runners to integrate with TeamCity without relying on internal implementation details.
As mentioned in my previous response, please try running
pytest --teamcitydirectly in a terminal. This will produce output in the form of ##teamcity[...] service message. Please note that running the tests directly from PyCharm is not applicable in this case, as there is no option to pass the --teamcity flag when using a standard PyCharm run configuration.These service messages can then be consumed by TeamCity, where they are parsed and displayed in the Tests tab of the build results, as shown below:
Tom Sun,
I am able to run `pytest --teamcity` after pip installing `teamcity-messages>=1.33` and can see the ##teamcity messages being emitted. Thank you for that!
Forgive me if I'm sounding redundant, but you mentioned that the PyCharm parsing of ##teamcity messages is open source as well. Would you be able to provide a link to where that code is? I'm curious about potentially helping improve the way `stdout` and `stderr` are output to the `Run` tool window.
Thanks again!
Thank you for the follow-up — and no worries at all.
To clarify, the part you’re referring to isn’t a separate proprietary parser in PyCharm itself — the TeamCity service messages support is actually based on the open-source teamcity-messages library. That’s the code that handles parsing and emitting ##teamcity messages, and it’s available publicly. Apologies for any confusion in my earlier explanation!
Here’s a code search that shows references to ##teamcity handling in the IntelliJ/PyCharm codebase:
🔗 https://github.com/search?q=repo%3AJetBrains%2Fintellij-community%20%23%23teamcity&type=code
And here’s the primary teamcity-messages repository on GitHub, which is the common library used across TeamCity integrations and many runners:
🔗 https://github.com/JetBrains/teamcity-messages
Hi Tom Sun,
Thank you again! I did just discover https://platform.jetbrains.com/ would you say this would be a better place to ask further questions regarding specific code in the IntelliJ Open Source Repository? If so I can move further questions there. If I end up making a post there, I can link it here as well for posterity.
Yes — that would be a more appropriate place.
For questions that dive into specific implementation details or code-level behavior in the IntelliJ Platform / IntelliJ IDEA Open Source repository, the JetBrains Platform community (https://platform.jetbrains.com/
) is indeed the best channel. So you’re much more likely to get accurate and in-depth answers there.
Thanks for your understanding, and please let us know if there’s anything else we can help with on the TeamCity side.
Hi Tom Sun,
you have stated that: “PyCharm’s IDE process monitors the stdout stream and parses lines starting with”
But I see all the ##teamcity messages in the console window.
So why is the IDE not parsing these messages ??