@sylix/coworker 2.0.11 → 2.0.14

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 (169) hide show
  1. package/dist/commands/slash/config.d.ts.map +1 -1
  2. package/dist/commands/slash/config.js +22 -4
  3. package/dist/commands/slash/config.js.map +1 -1
  4. package/dist/core/CoWorkerAgent.d.ts.map +1 -1
  5. package/dist/core/CoWorkerAgent.js +6 -3
  6. package/dist/core/CoWorkerAgent.js.map +1 -1
  7. package/dist/skills/defaults/accessibility/screen-reader-testing.md +545 -0
  8. package/dist/skills/defaults/accessibility/wcag-audit-patterns.md +555 -0
  9. package/dist/skills/defaults/ai-ml/rag.md +276 -0
  10. package/dist/skills/defaults/backend-development/api-design-principles.md +528 -0
  11. package/dist/skills/defaults/backend-development/api-design.md +285 -0
  12. package/dist/skills/defaults/backend-development/architecture-patterns.md +494 -0
  13. package/dist/skills/defaults/backend-development/async-python.md +237 -0
  14. package/dist/skills/defaults/backend-development/auth-implementation-patterns.md +638 -0
  15. package/dist/skills/defaults/backend-development/bazel-build-optimization.md +387 -0
  16. package/dist/skills/defaults/backend-development/billing-automation/SKILL.md +566 -0
  17. package/dist/skills/defaults/backend-development/code-review-excellence.md +538 -0
  18. package/dist/skills/defaults/backend-development/cqrs-implementation.md +554 -0
  19. package/dist/skills/defaults/backend-development/database-design.md +305 -0
  20. package/dist/skills/defaults/backend-development/debugging-strategies.md +536 -0
  21. package/dist/skills/defaults/backend-development/e2e-testing-patterns.md +544 -0
  22. package/dist/skills/defaults/backend-development/error-handling-patterns.md +641 -0
  23. package/dist/skills/defaults/backend-development/fastapi-templates.md +559 -0
  24. package/dist/skills/defaults/backend-development/fastapi.md +309 -0
  25. package/dist/skills/defaults/backend-development/git-advanced-workflows.md +405 -0
  26. package/dist/skills/defaults/backend-development/microservices-patterns.md +595 -0
  27. package/dist/skills/defaults/backend-development/microservices.md +284 -0
  28. package/dist/skills/defaults/backend-development/monorepo-management.md +623 -0
  29. package/dist/skills/defaults/backend-development/nodejs-backend-patterns.md +1048 -0
  30. package/dist/skills/defaults/backend-development/nx-workspace-patterns.md +457 -0
  31. package/dist/skills/defaults/backend-development/paypal-integration/SKILL.md +478 -0
  32. package/dist/skills/defaults/backend-development/pci-compliance/SKILL.md +480 -0
  33. package/dist/skills/defaults/backend-development/python-anti-patterns.md +349 -0
  34. package/dist/skills/defaults/backend-development/python-background-jobs.md +364 -0
  35. package/dist/skills/defaults/backend-development/python-code-style.md +360 -0
  36. package/dist/skills/defaults/backend-development/python-configuration.md +368 -0
  37. package/dist/skills/defaults/backend-development/python-design-patterns.md +296 -0
  38. package/dist/skills/defaults/backend-development/python-error-handling.md +323 -0
  39. package/dist/skills/defaults/backend-development/python-packaging.md +887 -0
  40. package/dist/skills/defaults/backend-development/python-performance-optimization.md +874 -0
  41. package/dist/skills/defaults/backend-development/python-project-structure.md +252 -0
  42. package/dist/skills/defaults/backend-development/python-resilience.md +376 -0
  43. package/dist/skills/defaults/backend-development/python-resource-management.md +421 -0
  44. package/dist/skills/defaults/backend-development/python-type-safety.md +428 -0
  45. package/dist/skills/defaults/backend-development/sql-optimization-patterns.md +509 -0
  46. package/dist/skills/defaults/backend-development/stripe-integration/SKILL.md +522 -0
  47. package/dist/skills/defaults/backend-development/turborepo-caching.md +376 -0
  48. package/dist/skills/defaults/blockchain/defi-protocol-templates.md +430 -0
  49. package/dist/skills/defaults/blockchain/nft-standards.md +364 -0
  50. package/dist/skills/defaults/blockchain/solidity-security.md +514 -0
  51. package/dist/skills/defaults/blockchain/web3-testing.md +360 -0
  52. package/dist/skills/defaults/business/competitive-landscape/SKILL.md +527 -0
  53. package/dist/skills/defaults/business/market-sizing-analysis/SKILL.md +451 -0
  54. package/dist/skills/defaults/business/startup-financial-modeling/SKILL.md +494 -0
  55. package/dist/skills/defaults/business/startup-metrics-framework/SKILL.md +564 -0
  56. package/dist/skills/defaults/business/team-composition-analysis.md +437 -0
  57. package/dist/skills/defaults/compliance/employment-contract-templates/SKILL.md +527 -0
  58. package/dist/skills/defaults/compliance/gdpr-data-handling/SKILL.md +630 -0
  59. package/dist/skills/defaults/data-engineering/airflow-dag-patterns.md +436 -0
  60. package/dist/skills/defaults/data-engineering/airflow.md +519 -0
  61. package/dist/skills/defaults/data-engineering/data-quality.md +583 -0
  62. package/dist/skills/defaults/data-engineering/dbt-transformation-patterns.md +482 -0
  63. package/dist/skills/defaults/data-engineering/dbt.md +556 -0
  64. package/dist/skills/defaults/data-engineering/ml-pipeline-workflow/SKILL.md +247 -0
  65. package/dist/skills/defaults/data-engineering/spark-optimization.md +348 -0
  66. package/dist/skills/defaults/data-engineering/spark.md +411 -0
  67. package/dist/skills/defaults/database/postgresql.md +202 -0
  68. package/dist/skills/defaults/debugging/systematic-debugging.md +249 -0
  69. package/dist/skills/defaults/devops/architecture-decision-records.md +448 -0
  70. package/dist/skills/defaults/devops/changelog-automation.md +580 -0
  71. package/dist/skills/defaults/devops/cicd.md +314 -0
  72. package/dist/skills/defaults/devops/cloud.md +263 -0
  73. package/dist/skills/defaults/devops/code-review-excellence.md +299 -0
  74. package/dist/skills/defaults/devops/cost-optimization.md +295 -0
  75. package/dist/skills/defaults/devops/deployment-pipeline-design.md +356 -0
  76. package/dist/skills/defaults/devops/docker.md +281 -0
  77. package/dist/skills/defaults/devops/git-workflows.md +205 -0
  78. package/dist/skills/defaults/devops/github-actions.md +311 -0
  79. package/dist/skills/defaults/devops/gitlab-ci-patterns.md +266 -0
  80. package/dist/skills/defaults/devops/hybrid-cloud-networking.md +241 -0
  81. package/dist/skills/defaults/devops/istio-traffic-management.md +327 -0
  82. package/dist/skills/defaults/devops/kubernetes.md +339 -0
  83. package/dist/skills/defaults/devops/linkerd-patterns.md +311 -0
  84. package/dist/skills/defaults/devops/multi-cloud-architecture.md +181 -0
  85. package/dist/skills/defaults/devops/observability.md +243 -0
  86. package/dist/skills/defaults/devops/openapi-spec-generation.md +1024 -0
  87. package/dist/skills/defaults/devops/postmortem-writing.md +396 -0
  88. package/dist/skills/defaults/devops/prometheus-configuration.md +265 -0
  89. package/dist/skills/defaults/devops/secrets-management.md +341 -0
  90. package/dist/skills/defaults/devops/service-mesh-observability.md +385 -0
  91. package/dist/skills/defaults/devops/terraform-module-library.md +244 -0
  92. package/dist/skills/defaults/finance/backtesting-frameworks/SKILL.md +663 -0
  93. package/dist/skills/defaults/finance/risk-metrics-calculation/SKILL.md +557 -0
  94. package/dist/skills/defaults/frontend/accessibility-compliance.md +420 -0
  95. package/dist/skills/defaults/frontend/design-system-patterns.md +337 -0
  96. package/dist/skills/defaults/frontend/interaction-design.md +327 -0
  97. package/dist/skills/defaults/frontend/javascript.md +311 -0
  98. package/dist/skills/defaults/frontend/modern-javascript-patterns.md +927 -0
  99. package/dist/skills/defaults/frontend/react-native-design.md +440 -0
  100. package/dist/skills/defaults/frontend/react.md +345 -0
  101. package/dist/skills/defaults/frontend/responsive-design.md +472 -0
  102. package/dist/skills/defaults/frontend/tailwind-design-system.md +337 -0
  103. package/dist/skills/defaults/frontend/typescript-advanced-types.md +724 -0
  104. package/dist/skills/defaults/frontend/typescript.md +334 -0
  105. package/dist/skills/defaults/frontend/visual-design-foundations.md +326 -0
  106. package/dist/skills/defaults/frontend/web-component-design.md +279 -0
  107. package/dist/skills/defaults/game-development/godot-gdscript-patterns.md +188 -0
  108. package/dist/skills/defaults/game-development/unity-ecs-patterns.md +594 -0
  109. package/dist/skills/defaults/kubernetes/gitops-workflow.md +285 -0
  110. package/dist/skills/defaults/kubernetes/gitops.md +280 -0
  111. package/dist/skills/defaults/kubernetes/helm-chart-scaffolding.md +553 -0
  112. package/dist/skills/defaults/kubernetes/helm.md +343 -0
  113. package/dist/skills/defaults/kubernetes/k8s-manifest-generator.md +501 -0
  114. package/dist/skills/defaults/kubernetes/k8s-security-policies.md +342 -0
  115. package/dist/skills/defaults/kubernetes/manifests.md +330 -0
  116. package/dist/skills/defaults/kubernetes/security.md +337 -0
  117. package/dist/skills/defaults/llm-application/embedding-strategies.md +608 -0
  118. package/dist/skills/defaults/llm-application/hybrid-search-implementation.md +570 -0
  119. package/dist/skills/defaults/llm-application/hybrid-search.md +570 -0
  120. package/dist/skills/defaults/llm-application/langchain-architecture.md +666 -0
  121. package/dist/skills/defaults/llm-application/langchain.md +259 -0
  122. package/dist/skills/defaults/llm-application/llm-evaluation.md +695 -0
  123. package/dist/skills/defaults/llm-application/prompt-engineering-patterns.md +449 -0
  124. package/dist/skills/defaults/llm-application/prompt-engineering.md +219 -0
  125. package/dist/skills/defaults/llm-application/rag-implementation.md +434 -0
  126. package/dist/skills/defaults/llm-application/similarity-search-patterns.md +560 -0
  127. package/dist/skills/defaults/llm-application/similarity-search.md +560 -0
  128. package/dist/skills/defaults/llm-application/vector-index-tuning.md +523 -0
  129. package/dist/skills/defaults/mobile/mobile-android-design.md +440 -0
  130. package/dist/skills/defaults/mobile/mobile-ios-design.md +266 -0
  131. package/dist/skills/defaults/monitoring/distributed-tracing.md +436 -0
  132. package/dist/skills/defaults/monitoring/grafana-dashboards.md +370 -0
  133. package/dist/skills/defaults/monitoring/prometheus-configuration.md +379 -0
  134. package/dist/skills/defaults/monitoring/slo-implementation.md +323 -0
  135. package/dist/skills/defaults/refactoring/code-refactoring.md +349 -0
  136. package/dist/skills/defaults/security/anti-reversing-techniques/SKILL.md +559 -0
  137. package/dist/skills/defaults/security/auditor.md +168 -0
  138. package/dist/skills/defaults/security/binary-analysis-patterns/SKILL.md +438 -0
  139. package/dist/skills/defaults/security/memory-forensics/SKILL.md +483 -0
  140. package/dist/skills/defaults/security/mtls-configuration.md +349 -0
  141. package/dist/skills/defaults/security/protocol-reverse-engineering/SKILL.md +520 -0
  142. package/dist/skills/defaults/security/sast-configuration.md +182 -0
  143. package/dist/skills/defaults/security/security.md +313 -0
  144. package/dist/skills/defaults/security/stride-analysis.md +273 -0
  145. package/dist/skills/defaults/security/threat-mitigation-mapping.md +290 -0
  146. package/dist/skills/defaults/systems/bash-defensive-patterns/SKILL.md +539 -0
  147. package/dist/skills/defaults/systems/bats-testing-patterns/SKILL.md +631 -0
  148. package/dist/skills/defaults/systems/go-concurrency-patterns.md +657 -0
  149. package/dist/skills/defaults/systems/memory-safety-patterns.md +605 -0
  150. package/dist/skills/defaults/systems/rust-async-patterns.md +519 -0
  151. package/dist/skills/defaults/systems/shellcheck-configuration/SKILL.md +456 -0
  152. package/dist/skills/defaults/team-collaboration/multi-reviewer-patterns.md +126 -0
  153. package/dist/skills/defaults/team-collaboration/parallel-feature-development.md +151 -0
  154. package/dist/skills/defaults/testing/javascript-testing-patterns.md +1021 -0
  155. package/dist/skills/defaults/testing/python-testing-patterns.md +351 -0
  156. package/dist/skills/defaults/testing/testing.md +332 -0
  157. package/dist/skills/defaults/workflows/context-driven-development.md +384 -0
  158. package/dist/skills/defaults/workflows/track-management.md +592 -0
  159. package/dist/skills/defaults/workflows/workflow-patterns.md +622 -0
  160. package/dist/skills/index.d.ts +11 -0
  161. package/dist/skills/index.d.ts.map +1 -0
  162. package/dist/skills/index.js +129 -0
  163. package/dist/skills/index.js.map +1 -0
  164. package/dist/utils/character.js +4 -4
  165. package/dist/utils/character.js.map +1 -1
  166. package/dist/utils/inputbar.d.ts.map +1 -1
  167. package/dist/utils/inputbar.js +7 -0
  168. package/dist/utils/inputbar.js.map +1 -1
  169. package/package.json +1 -1
@@ -0,0 +1,360 @@
1
+ ---
2
+ name: web3-testing
3
+ description: Test smart contracts comprehensively using Hardhat and Foundry with unit tests, integration tests, and mainnet forking
4
+ ---
5
+
6
+ # Web3 Smart Contract Testing
7
+
8
+ Master comprehensive testing strategies for smart contracts using Hardhat, Foundry, and advanced testing patterns.
9
+
10
+ ## When to Use This Skill
11
+
12
+ - Writing unit tests for smart contracts
13
+ - Setting up integration test suites
14
+ - Performing gas optimization testing
15
+ - Fuzzing for edge cases
16
+ - Forking mainnet for realistic testing
17
+ - Automating test coverage reporting
18
+ - Verifying contracts on Etherscan
19
+
20
+ ## Hardhat Testing Setup
21
+
22
+ ```javascript
23
+ require("@nomicfoundation/hardhat-toolbox");
24
+ require("@nomiclabs/hardhat-etherscan");
25
+ require("hardhat-gas-reporter");
26
+ require("solidity-coverage");
27
+
28
+ module.exports = {
29
+ solidity: {
30
+ version: "0.8.19",
31
+ settings: {
32
+ optimizer: {
33
+ enabled: true,
34
+ runs: 200,
35
+ },
36
+ },
37
+ },
38
+ networks: {
39
+ hardhat: {
40
+ forking: {
41
+ url: process.env.MAINNET_RPC_URL,
42
+ blockNumber: 15000000,
43
+ },
44
+ },
45
+ goerli: {
46
+ url: process.env.GOERLI_RPC_URL,
47
+ accounts: [process.env.PRIVATE_KEY],
48
+ },
49
+ },
50
+ gasReporter: {
51
+ enabled: true,
52
+ currency: "USD",
53
+ coinmarketcap: process.env.COINMARKETCAP_API_KEY,
54
+ },
55
+ etherscan: {
56
+ apiKey: process.env.ETHERSCAN_API_KEY,
57
+ },
58
+ };
59
+ ```
60
+
61
+ ## Unit Testing Patterns
62
+
63
+ ```javascript
64
+ const { expect } = require("chai");
65
+ const { ethers } = require("hardhat");
66
+ const {
67
+ loadFixture,
68
+ time,
69
+ } = require("@nomicfoundation/hardhat-network-helpers");
70
+
71
+ describe("Token Contract", function () {
72
+ async function deployTokenFixture() {
73
+ const [owner, addr1, addr2] = await ethers.getSigners();
74
+
75
+ const Token = await ethers.getContractFactory("Token");
76
+ const token = await Token.deploy();
77
+
78
+ return { token, owner, addr1, addr2 };
79
+ }
80
+
81
+ describe("Deployment", function () {
82
+ it("Should set the right owner", async function () {
83
+ const { token, owner } = await loadFixture(deployTokenFixture);
84
+ expect(await token.owner()).to.equal(owner.address);
85
+ });
86
+
87
+ it("Should assign total supply to owner", async function () {
88
+ const { token, owner } = await loadFixture(deployTokenFixture);
89
+ const ownerBalance = await token.balanceOf(owner.address);
90
+ expect(await token.totalSupply()).to.equal(ownerBalance);
91
+ });
92
+ });
93
+
94
+ describe("Transactions", function () {
95
+ it("Should transfer tokens between accounts", async function () {
96
+ const { token, owner, addr1 } = await loadFixture(deployTokenFixture);
97
+
98
+ await expect(token.transfer(addr1.address, 50)).to.changeTokenBalances(
99
+ token,
100
+ [owner, addr1],
101
+ [-50, 50],
102
+ );
103
+ });
104
+
105
+ it("Should fail if sender doesn't have enough tokens", async function () {
106
+ const { token, addr1, owner } = await loadFixture(deployTokenFixture);
107
+
108
+ await expect(
109
+ token.connect(addr1).transfer(owner.address, 1),
110
+ ).to.be.revertedWith("Insufficient balance");
111
+ });
112
+
113
+ it("Should emit Transfer event", async function () {
114
+ const { token, owner, addr1 } = await loadFixture(deployTokenFixture);
115
+
116
+ await expect(token.transfer(addr1.address, 50))
117
+ .to.emit(token, "Transfer")
118
+ .withArgs(owner.address, addr1.address, 50);
119
+ });
120
+ });
121
+
122
+ describe("Time-based tests", function () {
123
+ it("Should handle time-locked operations", async function () {
124
+ const { token } = await loadFixture(deployTokenFixture);
125
+ await time.increase(86400);
126
+ });
127
+ });
128
+ });
129
+ ```
130
+
131
+ ## Foundry Testing (Forge)
132
+
133
+ ```solidity
134
+ // SPDX-License-Identifier: MIT
135
+ pragma solidity ^0.8.0;
136
+
137
+ import "forge-std/Test.sol";
138
+ import "../src/Token.sol";
139
+
140
+ contract TokenTest is Test {
141
+ Token token;
142
+ address owner = address(1);
143
+ address user1 = address(2);
144
+ address user2 = address(3);
145
+
146
+ function setUp() public {
147
+ vm.prank(owner);
148
+ token = new Token();
149
+ }
150
+
151
+ function testInitialSupply() public {
152
+ assertEq(token.totalSupply(), 1000000 * 10**18);
153
+ }
154
+
155
+ function testTransfer() public {
156
+ vm.prank(owner);
157
+ token.transfer(user1, 100);
158
+
159
+ assertEq(token.balanceOf(user1), 100);
160
+ assertEq(token.balanceOf(owner), token.totalSupply() - 100);
161
+ }
162
+
163
+ function testFailTransferInsufficientBalance() public {
164
+ vm.prank(user1);
165
+ token.transfer(user2, 100);
166
+ }
167
+
168
+ function testCannotTransferToZeroAddress() public {
169
+ vm.prank(owner);
170
+ vm.expectRevert("Invalid recipient");
171
+ token.transfer(address(0), 100);
172
+ }
173
+
174
+ function testFuzzTransfer(uint256 amount) public {
175
+ vm.assume(amount > 0 && amount <= token.totalSupply());
176
+
177
+ vm.prank(owner);
178
+ token.transfer(user1, amount);
179
+
180
+ assertEq(token.balanceOf(user1), amount);
181
+ }
182
+
183
+ function testDealAndPrank() public {
184
+ vm.deal(user1, 10 ether);
185
+ vm.prank(user1);
186
+ assertEq(user1.balance, 10 ether);
187
+ }
188
+
189
+ function testForkMainnet() public {
190
+ vm.createSelectFork("https://eth-mainnet.alchemyapi.io/v2/...");
191
+ address dai = 0x6B175474E89094C44Da98b954EedeAC495271d0F;
192
+ assertEq(IERC20(dai).symbol(), "DAI");
193
+ }
194
+ }
195
+ ```
196
+
197
+ ## Advanced Testing Patterns
198
+
199
+ ### Snapshot and Revert
200
+
201
+ ```javascript
202
+ describe("Complex State Changes", function () {
203
+ let snapshotId;
204
+
205
+ beforeEach(async function () {
206
+ snapshotId = await network.provider.send("evm_snapshot");
207
+ });
208
+
209
+ afterEach(async function () {
210
+ await network.provider.send("evm_revert", [snapshotId]);
211
+ });
212
+
213
+ it("Test 1", async function () {
214
+ // Make state changes
215
+ });
216
+
217
+ it("Test 2", async function () {
218
+ // State reverted
219
+ });
220
+ });
221
+ ```
222
+
223
+ ### Mainnet Forking
224
+
225
+ ```javascript
226
+ describe("Mainnet Fork Tests", function () {
227
+ let uniswapRouter, dai;
228
+
229
+ before(async function () {
230
+ await network.provider.request({
231
+ method: "hardhat_reset",
232
+ params: [
233
+ {
234
+ forking: {
235
+ jsonRpcUrl: process.env.MAINNET_RPC_URL,
236
+ blockNumber: 15000000,
237
+ },
238
+ },
239
+ ],
240
+ });
241
+
242
+ uniswapRouter = await ethers.getContractAt(
243
+ "IUniswapV2Router",
244
+ "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D",
245
+ );
246
+
247
+ dai = await ethers.getContractAt(
248
+ "IERC20",
249
+ "0x6B175474E89094C44Da98b954EedeAC495271d0F",
250
+ );
251
+ });
252
+
253
+ it("Should swap on Uniswap", async function () {
254
+ // Test with real Uniswap contracts
255
+ });
256
+ });
257
+ ```
258
+
259
+ ### Impersonating Accounts
260
+
261
+ ```javascript
262
+ it("Should impersonate whale account", async function () {
263
+ const whaleAddress = "0x...";
264
+
265
+ await network.provider.request({
266
+ method: "hardhat_impersonateAccount",
267
+ params: [whaleAddress],
268
+ });
269
+
270
+ const whale = await ethers.getSigner(whaleAddress);
271
+
272
+ await dai
273
+ .connect(whale)
274
+ .transfer(addr1.address, ethers.utils.parseEther("1000"));
275
+ });
276
+ ```
277
+
278
+ ## Gas Optimization Testing
279
+
280
+ ```javascript
281
+ describe("Gas Optimization", function () {
282
+ it("Compare gas usage between implementations", async function () {
283
+ const Implementation1 = await ethers.getContractFactory("OptimizedContract");
284
+ const Implementation2 = await ethers.getContractFactory("UnoptimizedContract");
285
+
286
+ const contract1 = await Implementation1.deploy();
287
+ const contract2 = await Implementation2.deploy();
288
+
289
+ const tx1 = await contract1.doSomething();
290
+ const receipt1 = await tx1.wait();
291
+
292
+ const tx2 = await contract2.doSomething();
293
+ const receipt2 = await tx2.wait();
294
+
295
+ console.log("Optimized gas:", receipt1.gasUsed.toString());
296
+ console.log("Unoptimized gas:", receipt2.gasUsed.toString());
297
+
298
+ expect(receipt1.gasUsed).to.be.lessThan(receipt2.gasUsed);
299
+ });
300
+ });
301
+ ```
302
+
303
+ ## Coverage Reporting
304
+
305
+ ```bash
306
+ npx hardhat coverage
307
+
308
+ # Output shows:
309
+ # File | % Stmts | % Branch | % Funcs | % Lines |
310
+ # contracts/Token.sol | 100 | 90 | 100 | 95 |
311
+ ```
312
+
313
+ ## Contract Verification
314
+
315
+ ```javascript
316
+ await hre.run("verify:verify", {
317
+ address: contractAddress,
318
+ constructorArguments: [arg1, arg2],
319
+ });
320
+ ```
321
+
322
+ ```bash
323
+ npx hardhat verify --network mainnet CONTRACT_ADDRESS "Constructor arg1" "arg2"
324
+ ```
325
+
326
+ ## CI/CD Integration
327
+
328
+ ```yaml
329
+ name: Tests
330
+
331
+ on: [push, pull_request]
332
+
333
+ jobs:
334
+ test:
335
+ runs-on: ubuntu-latest
336
+
337
+ steps:
338
+ - uses: actions/checkout@v2
339
+ - uses: actions/setup-node@v2
340
+ with:
341
+ node-version: "16"
342
+
343
+ - run: npm install
344
+ - run: npx hardhat compile
345
+ - run: npx hardhat test
346
+ - run: npx hardhat coverage
347
+ ```
348
+
349
+ ## Best Practices
350
+
351
+ 1. **Test Coverage**: Aim for >90% coverage
352
+ 2. **Edge Cases**: Test boundary conditions
353
+ 3. **Gas Limits**: Verify functions don't hit block gas limit
354
+ 4. **Reentrancy**: Test for reentrancy vulnerabilities
355
+ 5. **Access Control**: Test unauthorized access attempts
356
+ 6. **Events**: Verify event emissions
357
+ 7. **Fixtures**: Use fixtures to avoid code duplication
358
+ 8. **Mainnet Fork**: Test with real contracts
359
+ 9. **Fuzzing**: Use property-based testing
360
+ 10. **CI/CD**: Automate testing on every commit