{"id":31902934,"url":"https://github.com/algorandfoundation/algorand-TypeScript-testing","last_synced_at":"2025-10-13T13:05:38.443Z","repository":{"id":272237106,"uuid":"863369826","full_name":"algorandfoundation/algorand-typescript-testing","owner":"algorandfoundation","description":null,"archived":false,"fork":false,"pushed_at":"2025-10-02T01:59:09.000Z","size":2073,"stargazers_count":3,"open_issues_count":1,"forks_count":3,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-10-02T03:32:53.258Z","etag":null,"topics":["algokit"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/algorandfoundation.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-09-26T07:18:44.000Z","updated_at":"2025-08-04T15:47:54.000Z","dependencies_parsed_at":"2025-02-21T02:23:42.669Z","dependency_job_id":"7991a27c-fb24-4234-bd05-bcfe17c43722","html_url":"https://github.com/algorandfoundation/algorand-typescript-testing","commit_stats":null,"previous_names":["algorandfoundation/algorand-typescript-testing"],"tags_count":74,"template":false,"template_full_name":null,"purl":"pkg:github/algorandfoundation/algorand-typescript-testing","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/algorandfoundation%2Falgorand-typescript-testing","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/algorandfoundation%2Falgorand-typescript-testing/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/algorandfoundation%2Falgorand-typescript-testing/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/algorandfoundation%2Falgorand-typescript-testing/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/algorandfoundation","download_url":"https://codeload.github.com/algorandfoundation/algorand-typescript-testing/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/algorandfoundation%2Falgorand-typescript-testing/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279015270,"owners_count":26085683,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-13T02:00:06.723Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["algokit"],"created_at":"2025-10-13T13:01:30.572Z","updated_at":"2025-10-13T13:05:38.437Z","avatar_url":"https://github.com/algorandfoundation.png","language":"TypeScript","funding_links":[],"categories":["Core Resources"],"sub_categories":["AlgoKit"],"readme":"# Algorand TypeScript Testing\n\n[![docs-repository](https://img.shields.io/badge/url-repository-74dfdc?logo=github\u0026style=flat.svg)](https://github.com/algorandfoundation/algorand-typescript-testing/)\n[![learn-AlgoKit](https://img.shields.io/badge/learn-AlgoKit-74dfdc?logo=algorand\u0026mac=flat.svg)](https://developer.algorand.org/algokit/)\n[![github-stars](https://img.shields.io/github/stars/algorandfoundation/algorand-typescript-testing?color=74dfdc\u0026logo=star\u0026style=flat)](https://github.com/algorandfoundation/algorand-typescript-testing)\n[![visitor-badge](https://api.visitorbadge.io/api/visitors?path=https%3A%2F%2Fgithub.com%2Falgorandfoundation%2Falgorand-typescript-testing\u0026countColor=%2374dfdc\u0026style=flat)](https://github.com/algorandfoundation/algorand-typescript-testing/)\n\n`algorand-typescript-testing` is a companion package to [Algorand Typescript](https://github.com/algorandfoundation/puya-ts/tree/main/packages/algo-ts) that enables efficient unit testing of Algorand TypeScript smart contracts in an offline environment. This package emulates key AVM behaviors without requiring a network connection, offering fast and reliable testing capabilities with a familiar TypeScript interface.\n\nThe `algorand-typescript-testing` package provides:\n\n- A simple interface for fast and reliable unit testing\n- An offline testing environment that simulates core AVM functionality\n- A familiar TypeScript experience, compatible with testing frameworks like [vitest](https://vitest.dev/), and [jest](https://jestjs.io/)\n\n## Quick Start\n\n`algorand-typescript` is a prerequisite for `algorand-typescript-testing`, providing stubs and type annotations for Algorand TypeScript syntax. It enhances code completion and type checking when writing smart contracts. Note that this code isn't directly executable in standard Node.js environment; it's compiled by `puya-ts` into TEAL for Algorand Network deployment.\n\nTraditionally, testing Algorand smart contracts involved deployment on sandboxed networks and interacting with live instances. While robust, this approach can be inefficient and lacks versatility for testing Algorand TypeScript code.\n\nEnter `algorand-typescript-testing`: it leverages TypeScript's rich testing ecosystem for unit testing without network deployment. This enables rapid iteration and granular logic testing.\n\n\u003e **NOTE**: While `algorand-typescript-testing` offers valuable unit testing capabilities, it's not a replacement for comprehensive testing. Use it alongside other test types, particularly those running against the actual Algorand Network, for thorough contract validation.\n\n### Prerequisites\n\n- Python 3.12 or later\n- [Algorand Python](https://github.com/algorandfoundation/puya)\n- Node.js 20.x or later\n- [Algorand TypeScript](https://github.com/algorandfoundation/puya-ts)\n\n### Installation\n\n`algorand-typescript-testing` is distributed via [npm](https://www.npmjs.com/package/@algorandfoundation/algorand-typescript-testing/). Install the package using `npm`:\n\n```bash\nnpm i @algorandfoundation/algorand-typescript-testing\n```\n\n### Testing your first contract\n\nLet's write a simple contract and test it using the `algorand-typescript-testing` framework.\n\n#### Configuring vitest\n\nIf you are using [vitest](https://vitest.dev/) with [@rollup/plugin-typescript](https://www.npmjs.com/package/@rollup/plugin-typescript) plugin, configure `puyaTsTransformer` as a `before` stage transformer of the `typescript` plugin in `vitest.config.mts` file.\n\n```typescript\nimport typescript from '@rollup/plugin-typescript'\nimport { defineConfig } from 'vitest/config'\nimport { puyaTsTransformer } from '@algorandfoundation/algorand-typescript-testing/vitest-transformer'\n\nexport default defineConfig({\n  esbuild: {},\n  test: {\n    setupFiles: 'vitest.setup.ts',\n  },\n  plugins: [\n    typescript({\n      transformers: {\n        before: [puyaTsTransformer],\n      },\n    }),\n  ],\n})\n```\n\n`algorand-typescript-testing` package also exposes additional equality testers which enables the smart contract developers to write terser test by avoiding type casting in assertions. It can setup in `beforeAll` hook point in the setup file, `vitest.setup.ts`.\n\n```typescript\nimport { beforeAll, expect } from 'vitest'\nimport { addEqualityTesters } from '@algorandfoundation/algorand-typescript-testing'\n\nbeforeAll(() =\u003e {\n  addEqualityTesters({ expect })\n})\n```\n\n#### Configuring jest\n\nIf you are using [jest](https://jestjs.io/) with [ts-jest](https://www.npmjs.com/package/ts-jest), [@jest/globals](https://www.npmjs.com/package/@jest/globals) and [ts-node](https://www.npmjs.com/package/ts-node) plugins, configure `puyaTsTransformer` as a `before` stage transformer of the `typescript` plugin in `jest.config.ts` file.\n\n```typescript\nimport { createDefaultEsmPreset, type JestConfigWithTsJest } from 'ts-jest'\n\nconst presetConfig = createDefaultEsmPreset({})\nconst jestConfig: JestConfigWithTsJest = {\n  ...presetConfig,\n  testMatch: ['**/*.test.ts'],\n  setupFilesAfterEnv: ['\u003crootDir\u003e/jest.setup.ts'],\n  transform: {\n    '^.+\\\\.tsx?$': [\n      'ts-jest',\n      {\n        useESM: true,\n        astTransformers: {\n          before: ['node_modules/@algorandfoundation/algorand-typescript-testing/test-transformer/jest-transformer.mjs'],\n        },\n      },\n    ],\n  },\n  extensionsToTreatAsEsm: ['.ts'],\n}\nexport default jestConfig\n```\n\n`algorand-typescript-testing` package also exposes additional equality testers which enables the smart contract developers to write terser test by avoiding type casting in assertions. It can setup in `beforeAll` hook point in the setup file, `jest.setup.ts`.\n\n```typescript\nimport { beforeAll, expect } from '@jest/globals'\nimport { addEqualityTesters } from '@algorandfoundation/algorand-typescript-testing'\n\nbeforeAll(() =\u003e {\n  addEqualityTesters({ expect })\n})\n```\n\nYou'll also need to run `jest` with the `--experimental-vm-modules` and `--experimental-require-module` flags in the `package.json`. This requires node 20.17 or greater.\n\n```json\n{\n  \"name\": \"puya-ts-demo\",\n  \"scripts\": {\n    \"test:jest\": \"tsc \u0026\u0026 node --experimental-vm-modules --experimental-require-module node_modules/jest/bin/jest\"\n  },\n  \"engines\": {\n    \"node\": \"\u003e=20.17\"\n  }\n}\n```\n\nThere is also a patch file `ts-jest+29.2.5.patch` that needs to be applied to `ts-jest` package to for the `puyaTsTransformer` to work with the test files.\n\n1. Place the file in `\u003crootDir\u003e\\patches` folder.\n1. Install [patch-package](https://www.npmjs.com/package/patch-package) package as a dev dependency.\n1. Add `\"postinstall\": \"patch-package\",` script in `package.json` file.\n   The patch will then be applied with every `npm install` call.\n\n```patch\ndiff --git a/node_modules/ts-jest/dist/legacy/compiler/ts-compiler.js b/node_modules/ts-jest/dist/legacy/compiler/ts-compiler.js\nindex 5198f8f..addb47c 100644\n--- a/node_modules/ts-jest/dist/legacy/compiler/ts-compiler.js\n+++ b/node_modules/ts-jest/dist/legacy/compiler/ts-compiler.js\n@@ -234,7 +234,7 @@ var TsCompiler = /** @class */ (function () {\n         var _a;\n         // Initialize memory cache for typescript compiler\n         this._parsedTsConfig.fileNames\n-            .filter(function (fileName) { return constants_1.TS_TSX_REGEX.test(fileName) \u0026\u0026 !_this.configSet.isTestFile(fileName); })\n+            .filter(function (fileName) { return constants_1.TS_TSX_REGEX.test(fileName); })\n             // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n             .forEach(function (fileName) { return _this._fileVersionCache.set(fileName, 0); });\n         /* istanbul ignore next */\n\n```\n\nAfter the setup, the examples provided using `vitest` can be converted to work with `jest` by simply swapping the `import {...} from 'vitest'` with `import {...} from '@jest/globals'`.\n\n#### Contract Definition\n\n```typescript\nimport { arc4, assert, Bytes, GlobalState, gtxn, LocalState, op, Txn, uint64, Uint64 } from '@algorandfoundation/algorand-typescript'\n\nexport default class VotingContract extends arc4.Contract {\n  topic = GlobalState({ initialValue: 'default_topic', key: Bytes('topic') })\n  votes = GlobalState({ initialValue: Uint64(0), key: Bytes('votes') })\n  voted = LocalState\u003cuint64\u003e({ key: Bytes('voted') })\n\n  @arc4.abimethod()\n  public setTopic(topic: string): void {\n    this.topic.value = topic\n  }\n  @arc4.abimethod()\n  public vote(pay: gtxn.PaymentTxn): boolean {\n    assert(op.Global.groupSize === 2, 'Expected 2 transactions')\n    assert(pay.amount === 10_000, 'Incorrect payment amount')\n    assert(pay.sender === Txn.sender, 'Payment sender must match transaction sender')\n\n    if (this.voted(Txn.sender).hasValue) {\n      return false // Already voted\n    }\n\n    this.votes.value = this.votes.value + 1\n    this.voted(Txn.sender).value = 1\n    return true\n  }\n\n  @arc4.abimethod({ readonly: true })\n  public getVotes(): uint64 {\n    return this.votes.value\n  }\n\n  public clearStateProgram(): boolean {\n    return true\n  }\n}\n```\n\n#### Test Definition\n\n```typescript\nimport { Uint64 } from '@algorandfoundation/algorand-typescript'\nimport { TestExecutionContext } from '@algorandfoundation/algorand-typescript-testing'\nimport { afterEach, describe, expect, test } from 'vitest'\nimport VotingContract from './contract.algo'\n\ndescribe('Voting contract', () =\u003e {\n  const ctx = new TestExecutionContext()\n  afterEach(() =\u003e {\n    ctx.reset()\n  })\n\n  test('vote function', () =\u003e {\n    // Initialize the contract within the testing context\n    const contract = ctx.contract.create(VotingContract)\n\n    const voter = ctx.defaultSender\n    const payment = ctx.any.txn.payment({\n      sender: voter,\n      amount: 10_000,\n    })\n\n    const result = contract.vote(payment)\n    expect(result).toEqual(true)\n    expect(contract.votes.value).toEqual(1)\n    expect(contract.voted(voter).value).toEqual(1)\n  })\n\n  test('setTopic function', () =\u003e {\n    // Initialize the contract within the testing context\n    const contract = ctx.contract.create(VotingContract)\n\n    const newTopic = ctx.any.string(10)\n    contract.setTopic(newTopic)\n    expect(contract.topic.value).toEqual(newTopic)\n  })\n\n  test('getVotes function', () =\u003e {\n    // Initialize the contract within the testing context\n    const contract = ctx.contract.create(VotingContract)\n\n    contract.votes.value = 5\n    const votes = contract.getVotes()\n    expect(votes).toEqual(5)\n  })\n})\n```\n\nThis example demonstrates key aspects of testing with `algorand-typescript-testing` for ARC4-based contracts:\n\n1. ARC4 Contract Features:\n\n   - Use of `arc4.Contract` as the base class for the contract.\n   - ABI methods defined using the `@arc4.abimethod` decorator.\n   - Readonly method annotation with `@arc4.abimethod({readonly: true})`.\n\n2. Testing ARC4 Contracts:\n\n   - Creation of an `arc4.Contract` instance within the test context.\n   - Use of `ctx.any` for generating random test data.\n   - Direct invocation of ABI methods on the contract instance.\n\n3. Transaction Handling:\n\n   - Use of `ctx.any.txn` to create test transactions.\n   - Passing transaction objects as parameters to contract methods.\n\n4. State Verification:\n   - Checking global and local state changes after method execution.\n   - Verifying return values from ABI methods.\n\n\u003e **NOTE**: Thorough testing is crucial in smart contract development due to their immutable nature post-deployment. Comprehensive unit and integration tests ensure contract validity and reliability. Optimizing for efficiency can significantly improve user experience by reducing transaction fees and simplifying interactions. Investing in robust testing and optimization practices is crucial and offers many benefits in the long run.\n\n### Next steps\n\nTo dig deeper into the capabilities of `algorand-typescript-testing`, continue with the following sections.\n\n#### Contents\n\n- [Testing Guide](./docs/testing-guide/index.md)\n- [Examples](./docs/examples.md)\n- [Coverage](./docs/coverage.md)\n- [FQA](./docs/faq.md)\n- [API Reference](./docs/api.md)\n- [Algorand TypeScript](./docs/algots.md)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falgorandfoundation%2Falgorand-TypeScript-testing","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falgorandfoundation%2Falgorand-TypeScript-testing","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falgorandfoundation%2Falgorand-TypeScript-testing/lists"}