Skip to content

Commit 2606be4

Browse files
committed
docs(pytest plugin) Examples
1 parent af10e08 commit 2606be4

File tree

2 files changed

+288
-0
lines changed

2 files changed

+288
-0
lines changed

docs/pytest-plugin/examples.md

Lines changed: 281 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,281 @@
1+
(pytest_plugin_examples)=
2+
3+
# Examples
4+
5+
The libtmux pytest plugin provides powerful fixtures for testing tmux-related functionality. Here are examples demonstrating how to use the plugin effectively in your test suite.
6+
7+
## Basic Test with Server Fixture
8+
9+
Testing a simple server connection:
10+
11+
```python
12+
def test_server_connection(server):
13+
"""Test that we can connect to a tmux server."""
14+
assert server is not None
15+
assert server.cmd('list-sessions').stderr == []
16+
```
17+
18+
## Session-based Tests
19+
20+
Testing session creation and properties:
21+
22+
```python
23+
def test_new_session(session):
24+
"""Test that the session fixture provides a working session."""
25+
assert session is not None
26+
assert session.session_name is not None
27+
28+
# Verify we can execute tmux commands in this session
29+
session.cmd('display-message', '-p', 'test message')
30+
31+
# Get information about the session
32+
session_info = session.cmd('display-message', '-p', '#{session_name}').stdout
33+
assert len(session_info) > 0
34+
```
35+
36+
## Window Management Tests
37+
38+
Testing window creation and manipulation:
39+
40+
```python
41+
def test_window_operations(session):
42+
"""Test window creation and properties."""
43+
# Create a new window
44+
window = session.new_window(window_name="test_window")
45+
assert window.window_name == "test_window"
46+
47+
# Rename the window
48+
window.rename_window("renamed_window")
49+
assert window.window_name == "renamed_window"
50+
51+
# Split the window
52+
pane = window.split_window()
53+
assert len(window.panes) == 2
54+
55+
# Send keys to pane
56+
pane.send_keys("echo 'Hello from test'", enter=True)
57+
58+
# Verify the output (need to give time for command to execute)
59+
import time
60+
time.sleep(0.5)
61+
output = pane.capture_pane()
62+
assert any("Hello from test" in line for line in output)
63+
```
64+
65+
## Pane Management Tests
66+
67+
Testing pane creation and interaction:
68+
69+
```python
70+
def test_pane_operations(pane):
71+
"""Test operations on a pane fixture."""
72+
# Send a command
73+
pane.send_keys("echo 'Testing pane operations'", enter=True)
74+
75+
# Wait for command to complete
76+
import time
77+
time.sleep(0.5)
78+
79+
# Capture output
80+
output = pane.capture_pane()
81+
assert any("Testing pane operations" in line for line in output)
82+
83+
# Split the pane
84+
new_pane = pane.split_window()
85+
assert new_pane is not None
86+
87+
# Verify we have two panes now
88+
window = pane.window
89+
assert len(window.panes) == 2
90+
```
91+
92+
## Testing with Custom Environment
93+
94+
Setting up a specific environment for tests:
95+
96+
```python
97+
def test_with_custom_environment(server):
98+
"""Test with a customized environment setup."""
99+
# Create a session with specific options
100+
custom_session = server.new_session(
101+
session_name="custom-test",
102+
kill_session=True,
103+
attach=False
104+
)
105+
106+
# Set session options
107+
custom_session.set_option("mouse", "on")
108+
custom_session.set_option("history-limit", "5000")
109+
110+
# Create multiple windows
111+
windows = [
112+
custom_session.new_window(window_name="window1"),
113+
custom_session.new_window(window_name="window2"),
114+
custom_session.new_window(window_name="window3")
115+
]
116+
117+
# Test window switching
118+
custom_session.switch_window(1)
119+
current = custom_session.attached_window
120+
assert current.window_name == "window2"
121+
122+
# Clean up
123+
custom_session.kill_session()
124+
125+
# Verify the session was killed
126+
sessions = server.list_sessions()
127+
assert not any(s.session_name == "custom-test" for s in sessions)
128+
```
129+
130+
## Testing Long-Running Commands
131+
132+
Handling commands that take time to execute:
133+
134+
```python
135+
def test_long_running_command(pane):
136+
"""Test interaction with long-running commands."""
137+
# Start a command that will run for a few seconds
138+
pane.send_keys("sleep 3 && echo 'Command completed'", enter=True)
139+
140+
# Verify command is running
141+
import time
142+
time.sleep(0.5) # Give time for the command to start
143+
144+
# Check immediate output (should not see completion message yet)
145+
output = pane.capture_pane()
146+
assert not any("Command completed" in line for line in output)
147+
148+
# Wait for command to complete
149+
time.sleep(3)
150+
151+
# Verify command completed
152+
output = pane.capture_pane()
153+
assert any("Command completed" in line for line in output)
154+
```
155+
156+
## Integration Testing with External Programs
157+
158+
Testing integration with other terminal programs:
159+
160+
```python
161+
def test_program_integration(pane):
162+
"""Test interaction with another terminal program."""
163+
# Start a text editor (nano is simple and widely available)
164+
pane.send_keys("nano", enter=True)
165+
166+
# Wait for nano to start
167+
import time
168+
time.sleep(1)
169+
170+
# Type some text
171+
pane.send_keys("This is a test file created by libtmux")
172+
173+
# Save the file (Ctrl+O)
174+
pane.send_keys("^O") # Ctrl+O
175+
time.sleep(0.5)
176+
pane.send_keys("test_file.txt", enter=True)
177+
178+
# Exit nano (Ctrl+X)
179+
pane.send_keys("^X") # Ctrl+X
180+
time.sleep(0.5)
181+
182+
# Verify the file was created
183+
pane.send_keys("cat test_file.txt", enter=True)
184+
time.sleep(0.5)
185+
186+
output = pane.capture_pane()
187+
assert any("This is a test file created by libtmux" in line for line in output)
188+
189+
# Clean up
190+
pane.send_keys("rm test_file.txt", enter=True)
191+
```
192+
193+
## Testing Error Conditions
194+
195+
Testing error handling:
196+
197+
```python
198+
def test_error_handling(pane):
199+
"""Test handling of command errors."""
200+
# Send a command that will fail
201+
pane.send_keys("command_that_does_not_exist", enter=True)
202+
203+
# Wait for the error to appear
204+
import time
205+
time.sleep(0.5)
206+
207+
# Capture the output
208+
output = pane.capture_pane()
209+
210+
# Verify error message appears
211+
assert any("command not found" in line.lower() for line in output)
212+
```
213+
214+
## Parametrized Tests
215+
216+
Using pytest parametrization with tmux fixtures:
217+
218+
```python
219+
import pytest
220+
221+
@pytest.mark.parametrize("window_name", ["test1", "test2", "test3"])
222+
def test_multiple_windows(session, window_name):
223+
"""Test creating windows with different names."""
224+
window = session.new_window(window_name=window_name)
225+
assert window.window_name == window_name
226+
227+
# Do something with each window
228+
pane = window.attached_pane
229+
pane.send_keys(f"echo 'Testing window {window_name}'", enter=True)
230+
231+
# Verify output
232+
import time
233+
time.sleep(0.5)
234+
output = pane.capture_pane()
235+
assert any(f"Testing window {window_name}" in line for line in output)
236+
```
237+
238+
## Best Practices for Testing with libtmux
239+
240+
1. **Keep tests isolated**: Each test should run in its own tmux environment to prevent interference
241+
2. **Add sufficient wait times**: Terminal commands take time to execute; add appropriate delays
242+
3. **Clean up after tests**: Kill sessions you create if not using the automatic fixtures
243+
4. **Use assertions effectively**: Verify both the state of tmux objects and the visible output
244+
5. **Handle slow commands**: For commands that may take variable time, implement polling rather than fixed waits
245+
246+
## Debugging Tests
247+
248+
If you're having trouble with your tmux tests, try these techniques:
249+
250+
```python
251+
def test_with_debugging(pane):
252+
"""Example showing debugging techniques."""
253+
# Capture initial state
254+
initial_state = pane.capture_pane()
255+
print(f"Initial pane state: {initial_state}")
256+
257+
# Send a command
258+
pane.send_keys("echo 'Debug test'", enter=True)
259+
260+
# Wait with diagnostic output
261+
import time
262+
for i in range(5):
263+
time.sleep(0.1)
264+
output = pane.capture_pane()
265+
print(f"Output after {i+1} wait cycle: {output}")
266+
267+
# Get tmux server information for debugging
268+
server_info = pane.server.cmd("info").stdout
269+
print(f"Server info: {server_info}")
270+
271+
# Get detailed window information
272+
window_info = pane.window.cmd("display-message", "-p", "#{window_id} #{window_name}").stdout
273+
print(f"Window info: {window_info}")
274+
275+
# Assert with detailed error
276+
expected_text = "Debug test"
277+
output = pane.capture_pane()
278+
if not any(expected_text in line for line in output):
279+
print(f"Failed to find '{expected_text}' in output: {output}")
280+
assert any(expected_text in line for line in output)
281+
```

docs/pytest-plugin/index.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,3 +147,10 @@ def set_home(
147147
:show-inheritance:
148148
:member-order: bysource
149149
```
150+
151+
## More
152+
153+
```{toctree}
154+
155+
examples
156+
```

0 commit comments

Comments
 (0)