@zimezone/z-command 1.1.1 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (282) hide show
  1. package/README.md +13 -1
  2. package/dist/commands/init.d.ts.map +1 -1
  3. package/dist/commands/init.js +34 -9
  4. package/dist/commands/init.js.map +1 -1
  5. package/package.json +8 -3
  6. package/templates.zip +0 -0
  7. package/templates/agents/accessibility-expert.agent.md +0 -56
  8. package/templates/agents/ai-engineer.agent.md +0 -61
  9. package/templates/agents/angular-architect.agent.md +0 -49
  10. package/templates/agents/api-designer.agent.md +0 -40
  11. package/templates/agents/api-documenter.agent.md +0 -161
  12. package/templates/agents/architect-review.agent.md +0 -146
  13. package/templates/agents/arm-cortex-expert.agent.md +0 -288
  14. package/templates/agents/azure-infra-engineer.agent.md +0 -57
  15. package/templates/agents/backend-architect.agent.md +0 -309
  16. package/templates/agents/backend-developer.agent.md +0 -61
  17. package/templates/agents/backend-security-coder.agent.md +0 -152
  18. package/templates/agents/bash-pro.agent.md +0 -285
  19. package/templates/agents/blockchain-developer.agent.md +0 -57
  20. package/templates/agents/build-engineer.agent.md +0 -56
  21. package/templates/agents/business-analyst.agent.md +0 -47
  22. package/templates/agents/c-pro.agent.md +0 -35
  23. package/templates/agents/c4-code.agent.md +0 -320
  24. package/templates/agents/c4-component.agent.md +0 -227
  25. package/templates/agents/c4-container.agent.md +0 -248
  26. package/templates/agents/c4-context.agent.md +0 -235
  27. package/templates/agents/cli-developer.agent.md +0 -57
  28. package/templates/agents/cloud-architect.agent.md +0 -56
  29. package/templates/agents/code-architect.agent.md +0 -63
  30. package/templates/agents/code-reviewer.agent.md +0 -49
  31. package/templates/agents/competitive-analyst.agent.md +0 -48
  32. package/templates/agents/conductor-validator.agent.md +0 -245
  33. package/templates/agents/context-manager.agent.md +0 -55
  34. package/templates/agents/cpp-pro.agent.md +0 -59
  35. package/templates/agents/csharp-developer.agent.md +0 -57
  36. package/templates/agents/csharp-pro.agent.md +0 -38
  37. package/templates/agents/customer-support.agent.md +0 -148
  38. package/templates/agents/data-engineer.agent.md +0 -55
  39. package/templates/agents/data-researcher.agent.md +0 -55
  40. package/templates/agents/data-scientist.agent.md +0 -56
  41. package/templates/agents/database-admin.agent.md +0 -142
  42. package/templates/agents/database-administrator.agent.md +0 -50
  43. package/templates/agents/database-architect.agent.md +0 -238
  44. package/templates/agents/database-optimizer.agent.md +0 -144
  45. package/templates/agents/debugger.agent.md +0 -30
  46. package/templates/agents/deployment-engineer.agent.md +0 -0
  47. package/templates/agents/devops-engineer.agent.md +0 -59
  48. package/templates/agents/devops-troubleshooter.agent.md +0 -138
  49. package/templates/agents/django-developer.agent.md +0 -50
  50. package/templates/agents/django-pro.agent.md +0 -159
  51. package/templates/agents/docs-architect.agent.md +0 -77
  52. package/templates/agents/documentation-engineer.agent.md +0 -57
  53. package/templates/agents/dotnet-architect.agent.md +0 -175
  54. package/templates/agents/dx-optimizer.agent.md +0 -63
  55. package/templates/agents/electron-pro.agent.md +0 -56
  56. package/templates/agents/elixir-pro.agent.md +0 -38
  57. package/templates/agents/embedded-systems.agent.md +0 -55
  58. package/templates/agents/error-detective.agent.md +0 -32
  59. package/templates/agents/event-sourcing-architect.agent.md +0 -42
  60. package/templates/agents/fastapi-pro.agent.md +0 -171
  61. package/templates/agents/fintech-engineer.agent.md +0 -57
  62. package/templates/agents/firmware-analyst.agent.md +0 -330
  63. package/templates/agents/flutter-expert.agent.md +0 -50
  64. package/templates/agents/frontend-developer.agent.md +0 -59
  65. package/templates/agents/frontend-security-coder.agent.md +0 -149
  66. package/templates/agents/fullstack-developer.agent.md +0 -46
  67. package/templates/agents/git-workflow-manager.agent.md +0 -57
  68. package/templates/agents/golang-pro.agent.md +0 -50
  69. package/templates/agents/graphql-architect.agent.md +0 -48
  70. package/templates/agents/haskell-pro.agent.md +0 -37
  71. package/templates/agents/hr-pro.agent.md +0 -105
  72. package/templates/agents/incident-responder.agent.md +0 -190
  73. package/templates/agents/ios-developer.agent.md +0 -198
  74. package/templates/agents/iot-engineer.agent.md +0 -56
  75. package/templates/agents/java-architect.agent.md +0 -48
  76. package/templates/agents/java-pro.agent.md +0 -156
  77. package/templates/agents/javascript-pro.agent.md +0 -35
  78. package/templates/agents/julia-pro.agent.md +0 -187
  79. package/templates/agents/kotlin-specialist.agent.md +0 -50
  80. package/templates/agents/laravel-specialist.agent.md +0 -50
  81. package/templates/agents/legacy-modernizer.agent.md +0 -56
  82. package/templates/agents/legal-advisor.agent.md +0 -49
  83. package/templates/agents/llm-architect.agent.md +0 -58
  84. package/templates/agents/malware-analyst.agent.md +0 -272
  85. package/templates/agents/mcp-developer.agent.md +0 -54
  86. package/templates/agents/mermaid-expert.agent.md +0 -39
  87. package/templates/agents/microservices-architect.agent.md +0 -47
  88. package/templates/agents/minecraft-bukkit-pro.agent.md +0 -104
  89. package/templates/agents/ml-engineer.agent.md +0 -56
  90. package/templates/agents/mlops-engineer.agent.md +0 -56
  91. package/templates/agents/mobile-developer.agent.md +0 -45
  92. package/templates/agents/mobile-security-coder.agent.md +0 -163
  93. package/templates/agents/monorepo-architect.agent.md +0 -44
  94. package/templates/agents/multi-agent-coordinator.agent.md +0 -55
  95. package/templates/agents/network-engineer.agent.md +0 -57
  96. package/templates/agents/nextjs-developer.agent.md +0 -48
  97. package/templates/agents/nlp-engineer.agent.md +0 -58
  98. package/templates/agents/observability-engineer.agent.md +0 -228
  99. package/templates/agents/payment-integration.agent.md +0 -56
  100. package/templates/agents/performance-engineer.agent.md +0 -167
  101. package/templates/agents/performance-optimizer.agent.md +0 -57
  102. package/templates/agents/php-pro.agent.md +0 -43
  103. package/templates/agents/platform-engineer.agent.md +0 -57
  104. package/templates/agents/posix-shell-pro.agent.md +0 -284
  105. package/templates/agents/postgres-pro.agent.md +0 -58
  106. package/templates/agents/product-manager.agent.md +0 -55
  107. package/templates/agents/project-manager.agent.md +0 -57
  108. package/templates/agents/prompt-engineer.agent.md +0 -58
  109. package/templates/agents/python-pro.agent.md +0 -48
  110. package/templates/agents/quant-analyst.agent.md +0 -32
  111. package/templates/agents/rails-expert.agent.md +0 -50
  112. package/templates/agents/react-specialist.agent.md +0 -49
  113. package/templates/agents/refactoring-specialist.agent.md +0 -56
  114. package/templates/agents/reference-builder.agent.md +0 -167
  115. package/templates/agents/research-analyst.agent.md +0 -63
  116. package/templates/agents/reverse-engineer.agent.md +0 -202
  117. package/templates/agents/risk-manager.agent.md +0 -41
  118. package/templates/agents/ruby-pro.agent.md +0 -35
  119. package/templates/agents/rust-pro.agent.md +0 -156
  120. package/templates/agents/sales-automator.agent.md +0 -35
  121. package/templates/agents/scala-pro.agent.md +0 -60
  122. package/templates/agents/scrum-master.agent.md +0 -54
  123. package/templates/agents/search-specialist.agent.md +0 -59
  124. package/templates/agents/security-analyst.agent.md +0 -57
  125. package/templates/agents/security-auditor.agent.md +0 -138
  126. package/templates/agents/security-engineer.agent.md +0 -57
  127. package/templates/agents/seo-authority-builder.agent.md +0 -116
  128. package/templates/agents/seo-cannibalization-detector.agent.md +0 -103
  129. package/templates/agents/seo-content-auditor.agent.md +0 -63
  130. package/templates/agents/seo-content-planner.agent.md +0 -88
  131. package/templates/agents/seo-content-refresher.agent.md +0 -98
  132. package/templates/agents/seo-content-writer.agent.md +0 -76
  133. package/templates/agents/seo-keyword-strategist.agent.md +0 -75
  134. package/templates/agents/seo-meta-optimizer.agent.md +0 -72
  135. package/templates/agents/seo-snippet-hunter.agent.md +0 -94
  136. package/templates/agents/seo-specialist.agent.md +0 -57
  137. package/templates/agents/seo-structure-architect.agent.md +0 -88
  138. package/templates/agents/service-mesh-expert.agent.md +0 -41
  139. package/templates/agents/sql-pro.agent.md +0 -146
  140. package/templates/agents/sre-engineer.agent.md +0 -58
  141. package/templates/agents/swift-expert.agent.md +0 -49
  142. package/templates/agents/task-distributor.agent.md +0 -47
  143. package/templates/agents/tdd-orchestrator.agent.md +0 -183
  144. package/templates/agents/technical-writer.agent.md +0 -48
  145. package/templates/agents/temporal-python-pro.agent.md +0 -349
  146. package/templates/agents/terraform-engineer.agent.md +0 -57
  147. package/templates/agents/terraform-specialist.agent.md +0 -137
  148. package/templates/agents/test-automator.agent.md +0 -203
  149. package/templates/agents/test-engineer.agent.md +0 -55
  150. package/templates/agents/threat-modeling-expert.agent.md +0 -44
  151. package/templates/agents/trend-analyst.agent.md +0 -47
  152. package/templates/agents/tutorial-engineer.agent.md +0 -118
  153. package/templates/agents/typescript-pro.agent.md +0 -48
  154. package/templates/agents/ui-designer.agent.md +0 -48
  155. package/templates/agents/ui-ux-designer.agent.md +0 -188
  156. package/templates/agents/ui-visual-validator.agent.md +0 -192
  157. package/templates/agents/ux-researcher.agent.md +0 -48
  158. package/templates/agents/vector-database-engineer.agent.md +0 -43
  159. package/templates/agents/vue-expert.agent.md +0 -48
  160. package/templates/agents/websocket-engineer.agent.md +0 -49
  161. package/templates/agents/workflow-orchestrator.agent.md +0 -48
  162. package/templates/skills/angular-migration/SKILL.md +0 -410
  163. package/templates/skills/api-design-principles/SKILL.md +0 -528
  164. package/templates/skills/api-design-principles/assets/api-design-checklist.md +0 -155
  165. package/templates/skills/api-design-principles/assets/rest-api-template.py +0 -182
  166. package/templates/skills/api-design-principles/references/graphql-schema-design.md +0 -583
  167. package/templates/skills/api-design-principles/references/rest-best-practices.md +0 -408
  168. package/templates/skills/architecture-decision-records/SKILL.md +0 -428
  169. package/templates/skills/architecture-patterns/SKILL.md +0 -494
  170. package/templates/skills/async-python-patterns/SKILL.md +0 -694
  171. package/templates/skills/auth-implementation-patterns/SKILL.md +0 -634
  172. package/templates/skills/changelog-automation/SKILL.md +0 -552
  173. package/templates/skills/code-review/SKILL.md +0 -62
  174. package/templates/skills/code-review-excellence/SKILL.md +0 -520
  175. package/templates/skills/competitive-landscape/SKILL.md +0 -479
  176. package/templates/skills/context-driven-development/SKILL.md +0 -385
  177. package/templates/skills/cost-optimization/SKILL.md +0 -274
  178. package/templates/skills/cqrs-implementation/SKILL.md +0 -554
  179. package/templates/skills/data-quality-frameworks/SKILL.md +0 -587
  180. package/templates/skills/data-storytelling/SKILL.md +0 -453
  181. package/templates/skills/database-migration/SKILL.md +0 -424
  182. package/templates/skills/dbt-transformation-patterns/SKILL.md +0 -561
  183. package/templates/skills/debugging-strategies/SKILL.md +0 -527
  184. package/templates/skills/defi-protocol-templates/SKILL.md +0 -454
  185. package/templates/skills/dependency-upgrade/SKILL.md +0 -409
  186. package/templates/skills/deployment-pipeline-design/SKILL.md +0 -359
  187. package/templates/skills/distributed-tracing/SKILL.md +0 -438
  188. package/templates/skills/dotnet-backend-patterns/SKILL.md +0 -815
  189. package/templates/skills/dotnet-backend-patterns/assets/repository-template.cs +0 -523
  190. package/templates/skills/dotnet-backend-patterns/assets/service-template.cs +0 -336
  191. package/templates/skills/dotnet-backend-patterns/references/dapper-patterns.md +0 -544
  192. package/templates/skills/dotnet-backend-patterns/references/ef-core-best-practices.md +0 -355
  193. package/templates/skills/e2e-testing-patterns/SKILL.md +0 -547
  194. package/templates/skills/employment-contract-templates/SKILL.md +0 -507
  195. package/templates/skills/error-handling-patterns/SKILL.md +0 -636
  196. package/templates/skills/event-store-design/SKILL.md +0 -437
  197. package/templates/skills/fastapi-templates/SKILL.md +0 -567
  198. package/templates/skills/git-advanced-workflows/SKILL.md +0 -400
  199. package/templates/skills/github-actions-templates/SKILL.md +0 -333
  200. package/templates/skills/go-concurrency-patterns/SKILL.md +0 -655
  201. package/templates/skills/grafana-dashboards/SKILL.md +0 -369
  202. package/templates/skills/helm-chart-scaffolding/SKILL.md +0 -544
  203. package/templates/skills/helm-chart-scaffolding/assets/Chart.yaml.template +0 -42
  204. package/templates/skills/helm-chart-scaffolding/assets/values.yaml.template +0 -185
  205. package/templates/skills/helm-chart-scaffolding/references/chart-structure.md +0 -500
  206. package/templates/skills/helm-chart-scaffolding/scripts/validate-chart.sh +0 -244
  207. package/templates/skills/javascript-testing-patterns/SKILL.md +0 -1025
  208. package/templates/skills/langchain-architecture/SKILL.md +0 -338
  209. package/templates/skills/llm-evaluation/SKILL.md +0 -471
  210. package/templates/skills/microservices-patterns/SKILL.md +0 -595
  211. package/templates/skills/modern-javascript-patterns/SKILL.md +0 -911
  212. package/templates/skills/monorepo-management/SKILL.md +0 -622
  213. package/templates/skills/nextjs-app-router-patterns/SKILL.md +0 -544
  214. package/templates/skills/nodejs-backend-patterns/SKILL.md +0 -1020
  215. package/templates/skills/nx-workspace-patterns/SKILL.md +0 -452
  216. package/templates/skills/openapi-spec-generation/SKILL.md +0 -1028
  217. package/templates/skills/paypal-integration/SKILL.md +0 -467
  218. package/templates/skills/pci-compliance/SKILL.md +0 -466
  219. package/templates/skills/postgresql/SKILL.md +0 -204
  220. package/templates/skills/projection-patterns/SKILL.md +0 -490
  221. package/templates/skills/prometheus-configuration/SKILL.md +0 -392
  222. package/templates/skills/prompt-engineering-patterns/SKILL.md +0 -201
  223. package/templates/skills/prompt-engineering-patterns/assets/few-shot-examples.json +0 -106
  224. package/templates/skills/prompt-engineering-patterns/assets/prompt-template-library.md +0 -246
  225. package/templates/skills/prompt-engineering-patterns/references/chain-of-thought.md +0 -399
  226. package/templates/skills/prompt-engineering-patterns/references/few-shot-learning.md +0 -369
  227. package/templates/skills/prompt-engineering-patterns/references/prompt-optimization.md +0 -414
  228. package/templates/skills/prompt-engineering-patterns/references/prompt-templates.md +0 -470
  229. package/templates/skills/prompt-engineering-patterns/references/system-prompts.md +0 -189
  230. package/templates/skills/prompt-engineering-patterns/scripts/optimize-prompt.py +0 -279
  231. package/templates/skills/python-packaging/SKILL.md +0 -870
  232. package/templates/skills/python-performance-optimization/SKILL.md +0 -869
  233. package/templates/skills/python-testing-patterns/SKILL.md +0 -907
  234. package/templates/skills/rag-implementation/SKILL.md +0 -403
  235. package/templates/skills/react-modernization/SKILL.md +0 -513
  236. package/templates/skills/react-native-architecture/SKILL.md +0 -671
  237. package/templates/skills/react-state-management/SKILL.md +0 -429
  238. package/templates/skills/risk-metrics-calculation/SKILL.md +0 -555
  239. package/templates/skills/rust-async-patterns/SKILL.md +0 -517
  240. package/templates/skills/secrets-management/SKILL.md +0 -346
  241. package/templates/skills/security-requirement-extraction/SKILL.md +0 -677
  242. package/templates/skills/security-review/SKILL.md +0 -78
  243. package/templates/skills/shellcheck-configuration/SKILL.md +0 -454
  244. package/templates/skills/similarity-search-patterns/SKILL.md +0 -558
  245. package/templates/skills/slo-implementation/SKILL.md +0 -329
  246. package/templates/skills/sql-optimization-patterns/SKILL.md +0 -493
  247. package/templates/skills/stripe-integration/SKILL.md +0 -442
  248. package/templates/skills/systematic-debugging/SKILL.md +0 -57
  249. package/templates/skills/tailwind-design-system/SKILL.md +0 -666
  250. package/templates/skills/temporal-python-testing/SKILL.md +0 -158
  251. package/templates/skills/temporal-python-testing/resources/integration-testing.md +0 -455
  252. package/templates/skills/temporal-python-testing/resources/local-setup.md +0 -553
  253. package/templates/skills/temporal-python-testing/resources/replay-testing.md +0 -462
  254. package/templates/skills/temporal-python-testing/resources/unit-testing.md +0 -328
  255. package/templates/skills/terraform-module-library/SKILL.md +0 -249
  256. package/templates/skills/terraform-module-library/references/aws-modules.md +0 -63
  257. package/templates/skills/test-driven-development/SKILL.md +0 -46
  258. package/templates/skills/threat-mitigation-mapping/SKILL.md +0 -745
  259. package/templates/skills/track-management/SKILL.md +0 -593
  260. package/templates/skills/typescript-advanced-types/SKILL.md +0 -717
  261. package/templates/skills/ui-ux-pro-max/SKILL.md +0 -352
  262. package/templates/skills/ui-ux-pro-max/data/charts.csv +0 -26
  263. package/templates/skills/ui-ux-pro-max/data/colors.csv +0 -97
  264. package/templates/skills/ui-ux-pro-max/data/icons.csv +0 -101
  265. package/templates/skills/ui-ux-pro-max/data/landing.csv +0 -31
  266. package/templates/skills/ui-ux-pro-max/data/products.csv +0 -97
  267. package/templates/skills/ui-ux-pro-max/data/prompts.csv +0 -24
  268. package/templates/skills/ui-ux-pro-max/data/react-performance.csv +0 -45
  269. package/templates/skills/ui-ux-pro-max/data/styles.csv +0 -59
  270. package/templates/skills/ui-ux-pro-max/data/typography.csv +0 -58
  271. package/templates/skills/ui-ux-pro-max/data/ui-reasoning.csv +0 -101
  272. package/templates/skills/ui-ux-pro-max/data/ux-guidelines.csv +0 -100
  273. package/templates/skills/ui-ux-pro-max/data/web-interface.csv +0 -31
  274. package/templates/skills/ui-ux-pro-max/scripts/core.py +0 -258
  275. package/templates/skills/ui-ux-pro-max/scripts/design_system.py +0 -547
  276. package/templates/skills/ui-ux-pro-max/scripts/search.py +0 -76
  277. package/templates/skills/uv-package-manager/SKILL.md +0 -831
  278. package/templates/skills/vector-index-tuning/SKILL.md +0 -521
  279. package/templates/skills/wcag-audit-patterns/SKILL.md +0 -555
  280. package/templates/skills/workflow-orchestration-patterns/SKILL.md +0 -316
  281. package/templates/skills/workflow-patterns/SKILL.md +0 -623
  282. package/templates/skills/writing-plans/SKILL.md +0 -64
@@ -1,907 +0,0 @@
1
- ---
2
- name: python-testing-patterns
3
- description: Implement comprehensive testing strategies with pytest, fixtures, mocking, and test-driven development. Use when writing Python tests, setting up test suites, or implementing testing best practices.
4
- ---
5
-
6
- # Python Testing Patterns
7
-
8
- Comprehensive guide to implementing robust testing strategies in Python using pytest, fixtures, mocking, parameterization, and test-driven development practices.
9
-
10
- ## When to Use This Skill
11
-
12
- - Writing unit tests for Python code
13
- - Setting up test suites and test infrastructure
14
- - Implementing test-driven development (TDD)
15
- - Creating integration tests for APIs and services
16
- - Mocking external dependencies and services
17
- - Testing async code and concurrent operations
18
- - Setting up continuous testing in CI/CD
19
- - Implementing property-based testing
20
- - Testing database operations
21
- - Debugging failing tests
22
-
23
- ## Core Concepts
24
-
25
- ### 1. Test Types
26
- - **Unit Tests**: Test individual functions/classes in isolation
27
- - **Integration Tests**: Test interaction between components
28
- - **Functional Tests**: Test complete features end-to-end
29
- - **Performance Tests**: Measure speed and resource usage
30
-
31
- ### 2. Test Structure (AAA Pattern)
32
- - **Arrange**: Set up test data and preconditions
33
- - **Act**: Execute the code under test
34
- - **Assert**: Verify the results
35
-
36
- ### 3. Test Coverage
37
- - Measure what code is exercised by tests
38
- - Identify untested code paths
39
- - Aim for meaningful coverage, not just high percentages
40
-
41
- ### 4. Test Isolation
42
- - Tests should be independent
43
- - No shared state between tests
44
- - Each test should clean up after itself
45
-
46
- ## Quick Start
47
-
48
- ```python
49
- # test_example.py
50
- def add(a, b):
51
- return a + b
52
-
53
- def test_add():
54
- """Basic test example."""
55
- result = add(2, 3)
56
- assert result == 5
57
-
58
- def test_add_negative():
59
- """Test with negative numbers."""
60
- assert add(-1, 1) == 0
61
-
62
- # Run with: pytest test_example.py
63
- ```
64
-
65
- ## Fundamental Patterns
66
-
67
- ### Pattern 1: Basic pytest Tests
68
-
69
- ```python
70
- # test_calculator.py
71
- import pytest
72
-
73
- class Calculator:
74
- """Simple calculator for testing."""
75
-
76
- def add(self, a: float, b: float) -> float:
77
- return a + b
78
-
79
- def subtract(self, a: float, b: float) -> float:
80
- return a - b
81
-
82
- def multiply(self, a: float, b: float) -> float:
83
- return a * b
84
-
85
- def divide(self, a: float, b: float) -> float:
86
- if b == 0:
87
- raise ValueError("Cannot divide by zero")
88
- return a / b
89
-
90
-
91
- def test_addition():
92
- """Test addition."""
93
- calc = Calculator()
94
- assert calc.add(2, 3) == 5
95
- assert calc.add(-1, 1) == 0
96
- assert calc.add(0, 0) == 0
97
-
98
-
99
- def test_subtraction():
100
- """Test subtraction."""
101
- calc = Calculator()
102
- assert calc.subtract(5, 3) == 2
103
- assert calc.subtract(0, 5) == -5
104
-
105
-
106
- def test_multiplication():
107
- """Test multiplication."""
108
- calc = Calculator()
109
- assert calc.multiply(3, 4) == 12
110
- assert calc.multiply(0, 5) == 0
111
-
112
-
113
- def test_division():
114
- """Test division."""
115
- calc = Calculator()
116
- assert calc.divide(6, 3) == 2
117
- assert calc.divide(5, 2) == 2.5
118
-
119
-
120
- def test_division_by_zero():
121
- """Test division by zero raises error."""
122
- calc = Calculator()
123
- with pytest.raises(ValueError, match="Cannot divide by zero"):
124
- calc.divide(5, 0)
125
- ```
126
-
127
- ### Pattern 2: Fixtures for Setup and Teardown
128
-
129
- ```python
130
- # test_database.py
131
- import pytest
132
- from typing import Generator
133
-
134
- class Database:
135
- """Simple database class."""
136
-
137
- def __init__(self, connection_string: str):
138
- self.connection_string = connection_string
139
- self.connected = False
140
-
141
- def connect(self):
142
- """Connect to database."""
143
- self.connected = True
144
-
145
- def disconnect(self):
146
- """Disconnect from database."""
147
- self.connected = False
148
-
149
- def query(self, sql: str) -> list:
150
- """Execute query."""
151
- if not self.connected:
152
- raise RuntimeError("Not connected")
153
- return [{"id": 1, "name": "Test"}]
154
-
155
-
156
- @pytest.fixture
157
- def db() -> Generator[Database, None, None]:
158
- """Fixture that provides connected database."""
159
- # Setup
160
- database = Database("sqlite:///:memory:")
161
- database.connect()
162
-
163
- # Provide to test
164
- yield database
165
-
166
- # Teardown
167
- database.disconnect()
168
-
169
-
170
- def test_database_query(db):
171
- """Test database query with fixture."""
172
- results = db.query("SELECT * FROM users")
173
- assert len(results) == 1
174
- assert results[0]["name"] == "Test"
175
-
176
-
177
- @pytest.fixture(scope="session")
178
- def app_config():
179
- """Session-scoped fixture - created once per test session."""
180
- return {
181
- "database_url": "postgresql://localhost/test",
182
- "api_key": "test-key",
183
- "debug": True
184
- }
185
-
186
-
187
- @pytest.fixture(scope="module")
188
- def api_client(app_config):
189
- """Module-scoped fixture - created once per test module."""
190
- # Setup expensive resource
191
- client = {"config": app_config, "session": "active"}
192
- yield client
193
- # Cleanup
194
- client["session"] = "closed"
195
-
196
-
197
- def test_api_client(api_client):
198
- """Test using api client fixture."""
199
- assert api_client["session"] == "active"
200
- assert api_client["config"]["debug"] is True
201
- ```
202
-
203
- ### Pattern 3: Parameterized Tests
204
-
205
- ```python
206
- # test_validation.py
207
- import pytest
208
-
209
- def is_valid_email(email: str) -> bool:
210
- """Check if email is valid."""
211
- return "@" in email and "." in email.split("@")[1]
212
-
213
-
214
- @pytest.mark.parametrize("email,expected", [
215
- ("user@example.com", True),
216
- ("test.user@domain.co.uk", True),
217
- ("invalid.email", False),
218
- ("@example.com", False),
219
- ("user@domain", False),
220
- ("", False),
221
- ])
222
- def test_email_validation(email, expected):
223
- """Test email validation with various inputs."""
224
- assert is_valid_email(email) == expected
225
-
226
-
227
- @pytest.mark.parametrize("a,b,expected", [
228
- (2, 3, 5),
229
- (0, 0, 0),
230
- (-1, 1, 0),
231
- (100, 200, 300),
232
- (-5, -5, -10),
233
- ])
234
- def test_addition_parameterized(a, b, expected):
235
- """Test addition with multiple parameter sets."""
236
- from test_calculator import Calculator
237
- calc = Calculator()
238
- assert calc.add(a, b) == expected
239
-
240
-
241
- # Using pytest.param for special cases
242
- @pytest.mark.parametrize("value,expected", [
243
- pytest.param(1, True, id="positive"),
244
- pytest.param(0, False, id="zero"),
245
- pytest.param(-1, False, id="negative"),
246
- ])
247
- def test_is_positive(value, expected):
248
- """Test with custom test IDs."""
249
- assert (value > 0) == expected
250
- ```
251
-
252
- ### Pattern 4: Mocking with unittest.mock
253
-
254
- ```python
255
- # test_api_client.py
256
- import pytest
257
- from unittest.mock import Mock, patch, MagicMock
258
- import requests
259
-
260
- class APIClient:
261
- """Simple API client."""
262
-
263
- def __init__(self, base_url: str):
264
- self.base_url = base_url
265
-
266
- def get_user(self, user_id: int) -> dict:
267
- """Fetch user from API."""
268
- response = requests.get(f"{self.base_url}/users/{user_id}")
269
- response.raise_for_status()
270
- return response.json()
271
-
272
- def create_user(self, data: dict) -> dict:
273
- """Create new user."""
274
- response = requests.post(f"{self.base_url}/users", json=data)
275
- response.raise_for_status()
276
- return response.json()
277
-
278
-
279
- def test_get_user_success():
280
- """Test successful API call with mock."""
281
- client = APIClient("https://api.example.com")
282
-
283
- mock_response = Mock()
284
- mock_response.json.return_value = {"id": 1, "name": "John Doe"}
285
- mock_response.raise_for_status.return_value = None
286
-
287
- with patch("requests.get", return_value=mock_response) as mock_get:
288
- user = client.get_user(1)
289
-
290
- assert user["id"] == 1
291
- assert user["name"] == "John Doe"
292
- mock_get.assert_called_once_with("https://api.example.com/users/1")
293
-
294
-
295
- def test_get_user_not_found():
296
- """Test API call with 404 error."""
297
- client = APIClient("https://api.example.com")
298
-
299
- mock_response = Mock()
300
- mock_response.raise_for_status.side_effect = requests.HTTPError("404 Not Found")
301
-
302
- with patch("requests.get", return_value=mock_response):
303
- with pytest.raises(requests.HTTPError):
304
- client.get_user(999)
305
-
306
-
307
- @patch("requests.post")
308
- def test_create_user(mock_post):
309
- """Test user creation with decorator syntax."""
310
- client = APIClient("https://api.example.com")
311
-
312
- mock_post.return_value.json.return_value = {"id": 2, "name": "Jane Doe"}
313
- mock_post.return_value.raise_for_status.return_value = None
314
-
315
- user_data = {"name": "Jane Doe", "email": "jane@example.com"}
316
- result = client.create_user(user_data)
317
-
318
- assert result["id"] == 2
319
- mock_post.assert_called_once()
320
- call_args = mock_post.call_args
321
- assert call_args.kwargs["json"] == user_data
322
- ```
323
-
324
- ### Pattern 5: Testing Exceptions
325
-
326
- ```python
327
- # test_exceptions.py
328
- import pytest
329
-
330
- def divide(a: float, b: float) -> float:
331
- """Divide a by b."""
332
- if b == 0:
333
- raise ZeroDivisionError("Division by zero")
334
- if not isinstance(a, (int, float)) or not isinstance(b, (int, float)):
335
- raise TypeError("Arguments must be numbers")
336
- return a / b
337
-
338
-
339
- def test_zero_division():
340
- """Test exception is raised for division by zero."""
341
- with pytest.raises(ZeroDivisionError):
342
- divide(10, 0)
343
-
344
-
345
- def test_zero_division_with_message():
346
- """Test exception message."""
347
- with pytest.raises(ZeroDivisionError, match="Division by zero"):
348
- divide(5, 0)
349
-
350
-
351
- def test_type_error():
352
- """Test type error exception."""
353
- with pytest.raises(TypeError, match="must be numbers"):
354
- divide("10", 5)
355
-
356
-
357
- def test_exception_info():
358
- """Test accessing exception info."""
359
- with pytest.raises(ValueError) as exc_info:
360
- int("not a number")
361
-
362
- assert "invalid literal" in str(exc_info.value)
363
- ```
364
-
365
- ## Advanced Patterns
366
-
367
- ### Pattern 6: Testing Async Code
368
-
369
- ```python
370
- # test_async.py
371
- import pytest
372
- import asyncio
373
-
374
- async def fetch_data(url: str) -> dict:
375
- """Fetch data asynchronously."""
376
- await asyncio.sleep(0.1)
377
- return {"url": url, "data": "result"}
378
-
379
-
380
- @pytest.mark.asyncio
381
- async def test_fetch_data():
382
- """Test async function."""
383
- result = await fetch_data("https://api.example.com")
384
- assert result["url"] == "https://api.example.com"
385
- assert "data" in result
386
-
387
-
388
- @pytest.mark.asyncio
389
- async def test_concurrent_fetches():
390
- """Test concurrent async operations."""
391
- urls = ["url1", "url2", "url3"]
392
- tasks = [fetch_data(url) for url in urls]
393
- results = await asyncio.gather(*tasks)
394
-
395
- assert len(results) == 3
396
- assert all("data" in r for r in results)
397
-
398
-
399
- @pytest.fixture
400
- async def async_client():
401
- """Async fixture."""
402
- client = {"connected": True}
403
- yield client
404
- client["connected"] = False
405
-
406
-
407
- @pytest.mark.asyncio
408
- async def test_with_async_fixture(async_client):
409
- """Test using async fixture."""
410
- assert async_client["connected"] is True
411
- ```
412
-
413
- ### Pattern 7: Monkeypatch for Testing
414
-
415
- ```python
416
- # test_environment.py
417
- import os
418
- import pytest
419
-
420
- def get_database_url() -> str:
421
- """Get database URL from environment."""
422
- return os.environ.get("DATABASE_URL", "sqlite:///:memory:")
423
-
424
-
425
- def test_database_url_default():
426
- """Test default database URL."""
427
- # Will use actual environment variable if set
428
- url = get_database_url()
429
- assert url
430
-
431
-
432
- def test_database_url_custom(monkeypatch):
433
- """Test custom database URL with monkeypatch."""
434
- monkeypatch.setenv("DATABASE_URL", "postgresql://localhost/test")
435
- assert get_database_url() == "postgresql://localhost/test"
436
-
437
-
438
- def test_database_url_not_set(monkeypatch):
439
- """Test when env var is not set."""
440
- monkeypatch.delenv("DATABASE_URL", raising=False)
441
- assert get_database_url() == "sqlite:///:memory:"
442
-
443
-
444
- class Config:
445
- """Configuration class."""
446
-
447
- def __init__(self):
448
- self.api_key = "production-key"
449
-
450
- def get_api_key(self):
451
- return self.api_key
452
-
453
-
454
- def test_monkeypatch_attribute(monkeypatch):
455
- """Test monkeypatching object attributes."""
456
- config = Config()
457
- monkeypatch.setattr(config, "api_key", "test-key")
458
- assert config.get_api_key() == "test-key"
459
- ```
460
-
461
- ### Pattern 8: Temporary Files and Directories
462
-
463
- ```python
464
- # test_file_operations.py
465
- import pytest
466
- from pathlib import Path
467
-
468
- def save_data(filepath: Path, data: str):
469
- """Save data to file."""
470
- filepath.write_text(data)
471
-
472
-
473
- def load_data(filepath: Path) -> str:
474
- """Load data from file."""
475
- return filepath.read_text()
476
-
477
-
478
- def test_file_operations(tmp_path):
479
- """Test file operations with temporary directory."""
480
- # tmp_path is a pathlib.Path object
481
- test_file = tmp_path / "test_data.txt"
482
-
483
- # Save data
484
- save_data(test_file, "Hello, World!")
485
-
486
- # Verify file exists
487
- assert test_file.exists()
488
-
489
- # Load and verify data
490
- data = load_data(test_file)
491
- assert data == "Hello, World!"
492
-
493
-
494
- def test_multiple_files(tmp_path):
495
- """Test with multiple temporary files."""
496
- files = {
497
- "file1.txt": "Content 1",
498
- "file2.txt": "Content 2",
499
- "file3.txt": "Content 3"
500
- }
501
-
502
- for filename, content in files.items():
503
- filepath = tmp_path / filename
504
- save_data(filepath, content)
505
-
506
- # Verify all files created
507
- assert len(list(tmp_path.iterdir())) == 3
508
-
509
- # Verify contents
510
- for filename, expected_content in files.items():
511
- filepath = tmp_path / filename
512
- assert load_data(filepath) == expected_content
513
- ```
514
-
515
- ### Pattern 9: Custom Fixtures and Conftest
516
-
517
- ```python
518
- # conftest.py
519
- """Shared fixtures for all tests."""
520
- import pytest
521
-
522
- @pytest.fixture(scope="session")
523
- def database_url():
524
- """Provide database URL for all tests."""
525
- return "postgresql://localhost/test_db"
526
-
527
-
528
- @pytest.fixture(autouse=True)
529
- def reset_database(database_url):
530
- """Auto-use fixture that runs before each test."""
531
- # Setup: Clear database
532
- print(f"Clearing database: {database_url}")
533
- yield
534
- # Teardown: Clean up
535
- print("Test completed")
536
-
537
-
538
- @pytest.fixture
539
- def sample_user():
540
- """Provide sample user data."""
541
- return {
542
- "id": 1,
543
- "name": "Test User",
544
- "email": "test@example.com"
545
- }
546
-
547
-
548
- @pytest.fixture
549
- def sample_users():
550
- """Provide list of sample users."""
551
- return [
552
- {"id": 1, "name": "User 1"},
553
- {"id": 2, "name": "User 2"},
554
- {"id": 3, "name": "User 3"},
555
- ]
556
-
557
-
558
- # Parametrized fixture
559
- @pytest.fixture(params=["sqlite", "postgresql", "mysql"])
560
- def db_backend(request):
561
- """Fixture that runs tests with different database backends."""
562
- return request.param
563
-
564
-
565
- def test_with_db_backend(db_backend):
566
- """This test will run 3 times with different backends."""
567
- print(f"Testing with {db_backend}")
568
- assert db_backend in ["sqlite", "postgresql", "mysql"]
569
- ```
570
-
571
- ### Pattern 10: Property-Based Testing
572
-
573
- ```python
574
- # test_properties.py
575
- from hypothesis import given, strategies as st
576
- import pytest
577
-
578
- def reverse_string(s: str) -> str:
579
- """Reverse a string."""
580
- return s[::-1]
581
-
582
-
583
- @given(st.text())
584
- def test_reverse_twice_is_original(s):
585
- """Property: reversing twice returns original."""
586
- assert reverse_string(reverse_string(s)) == s
587
-
588
-
589
- @given(st.text())
590
- def test_reverse_length(s):
591
- """Property: reversed string has same length."""
592
- assert len(reverse_string(s)) == len(s)
593
-
594
-
595
- @given(st.integers(), st.integers())
596
- def test_addition_commutative(a, b):
597
- """Property: addition is commutative."""
598
- assert a + b == b + a
599
-
600
-
601
- @given(st.lists(st.integers()))
602
- def test_sorted_list_properties(lst):
603
- """Property: sorted list is ordered."""
604
- sorted_lst = sorted(lst)
605
-
606
- # Same length
607
- assert len(sorted_lst) == len(lst)
608
-
609
- # All elements present
610
- assert set(sorted_lst) == set(lst)
611
-
612
- # Is ordered
613
- for i in range(len(sorted_lst) - 1):
614
- assert sorted_lst[i] <= sorted_lst[i + 1]
615
- ```
616
-
617
- ## Testing Best Practices
618
-
619
- ### Test Organization
620
-
621
- ```python
622
- # tests/
623
- # __init__.py
624
- # conftest.py # Shared fixtures
625
- # test_unit/ # Unit tests
626
- # test_models.py
627
- # test_utils.py
628
- # test_integration/ # Integration tests
629
- # test_api.py
630
- # test_database.py
631
- # test_e2e/ # End-to-end tests
632
- # test_workflows.py
633
- ```
634
-
635
- ### Test Naming
636
-
637
- ```python
638
- # Good test names
639
- def test_user_creation_with_valid_data():
640
- """Clear name describes what is being tested."""
641
- pass
642
-
643
-
644
- def test_login_fails_with_invalid_password():
645
- """Name describes expected behavior."""
646
- pass
647
-
648
-
649
- def test_api_returns_404_for_missing_resource():
650
- """Specific about inputs and expected outcomes."""
651
- pass
652
-
653
-
654
- # Bad test names
655
- def test_1(): # Not descriptive
656
- pass
657
-
658
-
659
- def test_user(): # Too vague
660
- pass
661
-
662
-
663
- def test_function(): # Doesn't explain what's tested
664
- pass
665
- ```
666
-
667
- ### Test Markers
668
-
669
- ```python
670
- # test_markers.py
671
- import pytest
672
-
673
- @pytest.mark.slow
674
- def test_slow_operation():
675
- """Mark slow tests."""
676
- import time
677
- time.sleep(2)
678
-
679
-
680
- @pytest.mark.integration
681
- def test_database_integration():
682
- """Mark integration tests."""
683
- pass
684
-
685
-
686
- @pytest.mark.skip(reason="Feature not implemented yet")
687
- def test_future_feature():
688
- """Skip tests temporarily."""
689
- pass
690
-
691
-
692
- @pytest.mark.skipif(os.name == "nt", reason="Unix only test")
693
- def test_unix_specific():
694
- """Conditional skip."""
695
- pass
696
-
697
-
698
- @pytest.mark.xfail(reason="Known bug #123")
699
- def test_known_bug():
700
- """Mark expected failures."""
701
- assert False
702
-
703
-
704
- # Run with:
705
- # pytest -m slow # Run only slow tests
706
- # pytest -m "not slow" # Skip slow tests
707
- # pytest -m integration # Run integration tests
708
- ```
709
-
710
- ### Coverage Reporting
711
-
712
- ```bash
713
- # Install coverage
714
- pip install pytest-cov
715
-
716
- # Run tests with coverage
717
- pytest --cov=myapp tests/
718
-
719
- # Generate HTML report
720
- pytest --cov=myapp --cov-report=html tests/
721
-
722
- # Fail if coverage below threshold
723
- pytest --cov=myapp --cov-fail-under=80 tests/
724
-
725
- # Show missing lines
726
- pytest --cov=myapp --cov-report=term-missing tests/
727
- ```
728
-
729
- ## Testing Database Code
730
-
731
- ```python
732
- # test_database_models.py
733
- import pytest
734
- from sqlalchemy import create_engine, Column, Integer, String
735
- from sqlalchemy.ext.declarative import declarative_base
736
- from sqlalchemy.orm import sessionmaker, Session
737
-
738
- Base = declarative_base()
739
-
740
-
741
- class User(Base):
742
- """User model."""
743
- __tablename__ = "users"
744
-
745
- id = Column(Integer, primary_key=True)
746
- name = Column(String(50))
747
- email = Column(String(100), unique=True)
748
-
749
-
750
- @pytest.fixture(scope="function")
751
- def db_session() -> Session:
752
- """Create in-memory database for testing."""
753
- engine = create_engine("sqlite:///:memory:")
754
- Base.metadata.create_all(engine)
755
-
756
- SessionLocal = sessionmaker(bind=engine)
757
- session = SessionLocal()
758
-
759
- yield session
760
-
761
- session.close()
762
-
763
-
764
- def test_create_user(db_session):
765
- """Test creating a user."""
766
- user = User(name="Test User", email="test@example.com")
767
- db_session.add(user)
768
- db_session.commit()
769
-
770
- assert user.id is not None
771
- assert user.name == "Test User"
772
-
773
-
774
- def test_query_user(db_session):
775
- """Test querying users."""
776
- user1 = User(name="User 1", email="user1@example.com")
777
- user2 = User(name="User 2", email="user2@example.com")
778
-
779
- db_session.add_all([user1, user2])
780
- db_session.commit()
781
-
782
- users = db_session.query(User).all()
783
- assert len(users) == 2
784
-
785
-
786
- def test_unique_email_constraint(db_session):
787
- """Test unique email constraint."""
788
- from sqlalchemy.exc import IntegrityError
789
-
790
- user1 = User(name="User 1", email="same@example.com")
791
- user2 = User(name="User 2", email="same@example.com")
792
-
793
- db_session.add(user1)
794
- db_session.commit()
795
-
796
- db_session.add(user2)
797
-
798
- with pytest.raises(IntegrityError):
799
- db_session.commit()
800
- ```
801
-
802
- ## CI/CD Integration
803
-
804
- ```yaml
805
- # .github/workflows/test.yml
806
- name: Tests
807
-
808
- on: [push, pull_request]
809
-
810
- jobs:
811
- test:
812
- runs-on: ubuntu-latest
813
-
814
- strategy:
815
- matrix:
816
- python-version: ["3.9", "3.10", "3.11", "3.12"]
817
-
818
- steps:
819
- - uses: actions/checkout@v3
820
-
821
- - name: Set up Python
822
- uses: actions/setup-python@v4
823
- with:
824
- python-version: ${{ matrix.python-version }}
825
-
826
- - name: Install dependencies
827
- run: |
828
- pip install -e ".[dev]"
829
- pip install pytest pytest-cov
830
-
831
- - name: Run tests
832
- run: |
833
- pytest --cov=myapp --cov-report=xml
834
-
835
- - name: Upload coverage
836
- uses: codecov/codecov-action@v3
837
- with:
838
- file: ./coverage.xml
839
- ```
840
-
841
- ## Configuration Files
842
-
843
- ```ini
844
- # pytest.ini
845
- [pytest]
846
- testpaths = tests
847
- python_files = test_*.py
848
- python_classes = Test*
849
- python_functions = test_*
850
- addopts =
851
- -v
852
- --strict-markers
853
- --tb=short
854
- --cov=myapp
855
- --cov-report=term-missing
856
- markers =
857
- slow: marks tests as slow
858
- integration: marks integration tests
859
- unit: marks unit tests
860
- e2e: marks end-to-end tests
861
- ```
862
-
863
- ```toml
864
- # pyproject.toml
865
- [tool.pytest.ini_options]
866
- testpaths = ["tests"]
867
- python_files = ["test_*.py"]
868
- addopts = [
869
- "-v",
870
- "--cov=myapp",
871
- "--cov-report=term-missing",
872
- ]
873
-
874
- [tool.coverage.run]
875
- source = ["myapp"]
876
- omit = ["*/tests/*", "*/migrations/*"]
877
-
878
- [tool.coverage.report]
879
- exclude_lines = [
880
- "pragma: no cover",
881
- "def __repr__",
882
- "raise AssertionError",
883
- "raise NotImplementedError",
884
- ]
885
- ```
886
-
887
- ## Resources
888
-
889
- - **pytest documentation**: https://docs.pytest.org/
890
- - **unittest.mock**: https://docs.python.org/3/library/unittest.mock.html
891
- - **hypothesis**: Property-based testing
892
- - **pytest-asyncio**: Testing async code
893
- - **pytest-cov**: Coverage reporting
894
- - **pytest-mock**: pytest wrapper for mock
895
-
896
- ## Best Practices Summary
897
-
898
- 1. **Write tests first** (TDD) or alongside code
899
- 2. **One assertion per test** when possible
900
- 3. **Use descriptive test names** that explain behavior
901
- 4. **Keep tests independent** and isolated
902
- 5. **Use fixtures** for setup and teardown
903
- 6. **Mock external dependencies** appropriately
904
- 7. **Parametrize tests** to reduce duplication
905
- 8. **Test edge cases** and error conditions
906
- 9. **Measure coverage** but focus on quality
907
- 10. **Run tests in CI/CD** on every commit