Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Renamed algorandFixture's beforeEach to newScope #362

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 53 additions & 6 deletions docs/capabilities/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,37 @@ import { algorandFixture } from '@algorandfoundation/algokit-utils/testing'

### Using with Jest

To integrate with [Jest](https://jestjs.io/) you need to pass the `fixture.beforeEach` method into Jest's `beforeEach` method and then within each test you can access `fixture.context` to access per-test isolated fixture values.
To integrate with [Jest](https://jestjs.io/) you need to pass the `fixture.newScope` method into Jest's `beforeEach` method (for per test isolation) or `beforeAll` method (for test suite isolation) and then within each test you can access `fixture.context` to access the isolated fixture values.

#### Per-test isolation

```typescript
import { describe, test, beforeEach } from '@jest/globals'
import { algorandFixture } from './testing'

describe('MY MODULE', () => {
const fixture = algorandFixture()
beforeEach(fixture.beforeEach, 10_000)
beforeEach(fixture.newScope, 10_000) // Add a 10s timeout to cater for occasionally slow LocalNet calls

test('MY TEST', async () => {
const { algorand, testAccount /* ... */ } = fixture.context

// Test stuff!
})
})
```

Occasionally there may be a delay when first running the fixture setup so we add a 10s timeout to avoid intermittent test failures (`10_000`).

#### Test suite isolation

```typescript
import { describe, test, beforeAll } from '@jest/globals'
import { algorandFixture } from './testing'

describe('MY MODULE', () => {
const fixture = algorandFixture()
beforeAll(fixture.newScope, 10_000) // Add a 10s timeout to cater for occasionally slow LocalNet calls

test('MY TEST', async () => {
const { algorand, testAccount /* ... */ } = fixture.context
Expand All @@ -46,15 +68,37 @@ Occasionally there may be a delay when first running the fixture setup so we add

### Using with vitest

To integrate with [vitest](https://vitest.dev/) you need to pass the `fixture.beforeEach` method into vitest's `beforeEach` method and then within each test you can access `fixture.context` to access per-test isolated fixture values.
To integrate with [vitest](https://vitest.dev/) you need to pass the `fixture.beforeEach` method into vitest's `beforeEach` method (for per test isolation) or `beforeAll` method (for test suite isolation) and then within each test you can access `fixture.context` to access the isolated fixture values.

#### Per-test isolation

```typescript
import { describe, test, beforeEach } from 'vitest'
import { algorandFixture } from './testing'

describe('MY MODULE', () => {
const fixture = algorandFixture()
beforeEach(fixture.beforeEach, 10_000)
beforeEach(fixture.newScope, 10_000) // Add a 10s timeout to cater for occasionally slow LocalNet calls

test('MY TEST', async () => {
const { algorand, testAccount /* ... */ } = fixture.context

// Test stuff!
})
})
```

Occasionally there may be a delay when first running the fixture setup so we add a 10s timeout to avoid intermittent test failures (`10_000`).

#### Test suite isolation

```typescript
import { describe, test, beforeAll } from 'vitest'
import { algorandFixture } from './testing'

describe('MY MODULE', () => {
const fixture = algorandFixture()
beforeAll(fixture.newScope, 10_000) // Add a 10s timeout to cater for occasionally slow LocalNet calls

test('MY TEST', async () => {
const { algorand, testAccount /* ... */ } = fixture.context
Expand All @@ -64,6 +108,8 @@ describe('MY MODULE', () => {
})
```

Occasionally there may be a delay when first running the fixture setup so we add a 10s timeout to avoid intermittent test failures (`10_000`).

### Fixture configuration

When calling `algorandFixture()` you can optionally pass in some fixture configuration, with any of these properties (all optional):
Expand All @@ -72,6 +118,7 @@ When calling `algorandFixture()` you can optionally pass in some fixture configu
- `indexer?: Indexer` - An optional indexer client, if not specified then it will create one against environment variables defined network (if present) or default LocalNet
- `kmd?: Kmd` - An optional kmd client, if not specified then it will create one against environment variables defined network (if present) or default LocalNet
- `testAccountFunding?: AlgoAmount` - The [amount](./amount.md) of funds to allocate to the default testing account, if not specified then it will get `10` ALGO
- `accountGetter?: (algod: Algodv2, kmd?: Kmd) => Promise<Account>` - Optional override for how to get an account; this allows you to retrieve test accounts from a known or cached list of accounts.

### Using the fixture context

Expand All @@ -84,7 +131,7 @@ The `fixture.context` property is of type [`AlgorandTestAutomationContext`](../c
- `transactionLogger: TransactionLogger` - Transaction logger that will log transaction IDs for all transactions issued by `algod`
- `testAccount: Account` - Funded test account that is ephemerally created for each test
- `generateAccount: (params: GetTestAccountParams) => Promise<Account>` - Generate and fund an additional ephemerally created account
- `waitForIndexer: () => Promise<void>` - Wait for the indexer to catch up with all transactions logged by transactionLogger
- `waitForIndexer()` - Waits for indexer to catch up with that latest transaction that has been captured by the `transactionLogger` in the Algorand fixture
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- `waitForIndexer()` - Waits for indexer to catch up with that latest transaction that has been captured by the `transactionLogger` in the Algorand fixture
- `waitForIndexer()` - Waits for indexer to catch up with the latest transaction that has been captured by the `transactionLogger` in the Algorand fixture

- `waitForIndexerTransaction: (transactionId: string) => Promise<TransactionLookupResult>` - Wait for the indexer to catch up with the given transaction ID

## Log capture fixture
Expand Down Expand Up @@ -170,7 +217,7 @@ This means it's easy to create tests that are flaky and have intermittent test f
The testing capability provides mechanisms for waiting for indexer to catch up, namely:

- `algotesting.runWhenIndexerCaughtUp(run: () => Promise<T>)` - Executes the given action every 200ms up to 20 times until there is no longer an error with a `status` property with `404` and then returns the result of the action; this will work for any call that calls indexer APIs expecting to return a single record
- `algorandFixture.waitForIndexer()` - Waits for indexer to catch up with all transactions that have been captured by the `transactionLogger` in the Algorand fixture
- `algorandFixture.waitForIndexer()` - Waits for indexer to catch up with that latest transaction that has been captured by the `transactionLogger` in the Algorand fixture
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- `algorandFixture.waitForIndexer()` - Waits for indexer to catch up with that latest transaction that has been captured by the `transactionLogger` in the Algorand fixture
- `algorandFixture.waitForIndexer()` - Waits for indexer to catch up with the latest transaction that has been captured by the `transactionLogger` in the Algorand fixture

- `algorandFixture.waitForIndexerTransaction(transactionId)` - Waits for indexer to catch up with the single transaction of the given ID

## Logging transactions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Testing framework agnostic handler method to run after each test to reset the lo

#### Defined in

[src/types/testing.ts:113](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L113)
[src/types/testing.ts:158](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L158)

___

Expand All @@ -53,7 +53,7 @@ Testing framework agnostic handler method to run before each test to prepare the

#### Defined in

[src/types/testing.ts:109](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L109)
[src/types/testing.ts:154](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L154)

## Accessors

Expand All @@ -69,4 +69,4 @@ The test logger instance for the current test

#### Defined in

[src/types/testing.ts:105](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L105)
[src/types/testing.ts:150](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L150)
74 changes: 69 additions & 5 deletions docs/code/interfaces/types_testing.AlgorandFixture.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ An Algorand automated testing fixture
### Properties

- [beforeEach](types_testing.AlgorandFixture.md#beforeeach)
- [newScope](types_testing.AlgorandFixture.md#newscope)

### Accessors

Expand All @@ -23,7 +24,66 @@ An Algorand automated testing fixture

• **beforeEach**: () => `Promise`\<`void`\>

Testing framework agnostic handler method to run before each test to prepare the `context` for that test.
**`Deprecated`**

Use newScope instead.
Testing framework agnostic handler method to run before each test to prepare the `context` for that test with per test isolation.

#### Type declaration

▸ (): `Promise`\<`void`\>

##### Returns

`Promise`\<`void`\>

#### Defined in

[src/types/testing.ts:92](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L92)

___

### newScope

• **newScope**: () => `Promise`\<`void`\>

Creates a new isolated fixture scope (clean transaction logger, AlgorandClient, testAccount, etc.).

You can call this from any testing framework specific hook method to control when you want a new scope.

**`Example`**

```typescript
describe('MY MODULE', () => {
const fixture = algorandFixture()
beforeEach(fixture.newScope, 10_000) // Add a 10s timeout to cater for occasionally slow LocalNet calls

test('MY TEST', async () => {
const { algorand, testAccount } = fixture.context

// Test stuff!
})
})
```

**`Example`**

```typescript
describe('MY MODULE', () => {
const fixture = algorandFixture()
beforeAll(fixture.newScope, 10_000) // Add a 10s timeout to cater for occasionally slow LocalNet calls

test('test1', async () => {
const { algorand, testAccount } = fixture.context

// Test stuff!
})
test('test2', async () => {
const { algorand, testAccount } = fixture.context
// algorand and testAccount are the same as in test1
})
})
```

#### Type declaration

Expand All @@ -35,7 +95,7 @@ Testing framework agnostic handler method to run before each test to prepare the

#### Defined in

[src/types/testing.ts:87](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L87)
[src/types/testing.ts:132](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L132)

## Accessors

Expand All @@ -45,13 +105,15 @@ Testing framework agnostic handler method to run before each test to prepare the

Retrieve an `AlgorandClient` loaded with the current context, including testAccount and any generated accounts loaded as signers.

If you haven't called `newScope` then this will return an `AlgorandClient` instance with no test context loaded yet and no transaction logger loaded. This is useful if you want to do some basic setup in a `beforeAll` method etc..

#### Returns

[`AlgorandClient`](../classes/types_algorand_client.AlgorandClient.md)

#### Defined in

[src/types/testing.ts:82](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L82)
[src/types/testing.ts:86](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L86)

___

Expand All @@ -62,6 +124,8 @@ ___
Retrieve the current context.
Useful with destructuring.

If you haven't called `newScope` then this will throw an error.

#### Returns

[`AlgorandTestAutomationContext`](types_testing.AlgorandTestAutomationContext.md)
Expand All @@ -70,10 +134,10 @@ Useful with destructuring.

```typescript
test('My test', () => {
const {algod, indexer, testAccount, ...} = algorand.context
const {algod, indexer, testAccount, ...} = fixture.context
})
```

#### Defined in

[src/types/testing.ts:77](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L77)
[src/types/testing.ts:79](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L79)
6 changes: 3 additions & 3 deletions docs/code/interfaces/types_testing.LogSnapshotConfig.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Any accounts/addresses to replace the address for predictably

#### Defined in

[src/types/testing.ts:98](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L98)
[src/types/testing.ts:143](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L143)

___

Expand All @@ -38,7 +38,7 @@ Any app IDs to replace predictably

#### Defined in

[src/types/testing.ts:100](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L100)
[src/types/testing.ts:145](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L145)

___

Expand All @@ -50,4 +50,4 @@ Any transaction IDs or transactions to replace the ID for predictably

#### Defined in

[src/types/testing.ts:96](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L96)
[src/types/testing.ts:141](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/types/testing.ts#L141)
40 changes: 20 additions & 20 deletions docs/code/modules/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,35 +75,48 @@ The fixture
**`Example`**

```typescript
const algorand = algorandFixture()
const fixture = algorandFixture()

beforeEach(algorand.beforeEach, 10_000)
beforeEach(fixture.newScope, 10_000)

test('My test', async () => {
const {algod, indexer, testAccount, ...} = algorand.context
const {algod, indexer, testAccount, ...} = fixture.context
// test things...
})
```

**`Example`**

```typescript
const algorand = algorandFixture({
const fixture = algorandFixture()

beforeAll(fixture.newScope, 10_000)

test('My test', async () => {
const {algod, indexer, testAccount, ...} = fixture.context
// test things...
})
```

**`Example`**

```typescript
const fixture = algorandFixture({
algod: new Algodv2('localhost', 12345, 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'),
// ...
})

beforeEach(algorand.beforeEach, 10_000)
beforeEach(fixture.newScope, 10_000)

test('My test', async () => {
const {algod, indexer, testAccount, ...} = algorand.context
const {algod, indexer, testAccount, ...} = fixture.context
// test things...
})
```

#### Defined in

[src/testing/fixtures/algorand-fixture.ts:48](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/testing/fixtures/algorand-fixture.ts#L48)
[src/testing/fixtures/algorand-fixture.ts:60](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/testing/fixtures/algorand-fixture.ts#L60)

▸ **algorandFixture**(`fixtureConfig`, `config`): [`AlgorandFixture`](../interfaces/types_testing.AlgorandFixture.md)

Expand All @@ -130,19 +143,6 @@ By default it tests against an environment variable specified client
a default LocalNet instance, but you can pass in an algod, indexer
and/or kmd if you want to test against an explicitly defined network.

**`Example`**

```typescript
const algorand = algorandFixture(undefined, getConfigFromEnvOrDefaults())

beforeEach(algorand.beforeEach, 10_000)

test('My test', async () => {
const {algod, indexer, testAccount, ...} = algorand.context
// test things...
})
```

#### Defined in

[src/testing/fixtures/algorand-fixture.ts:75](https://github.com/algorandfoundation/algokit-utils-ts/blob/main/src/testing/fixtures/algorand-fixture.ts#L75)
Expand Down
2 changes: 1 addition & 1 deletion src/app-deploy.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { LogicError } from './types/logic-error'

describe('deploy-app', () => {
const localnet = algorandFixture()
beforeEach(localnet.beforeEach, 10_000)
beforeEach(localnet.newScope, 10_000)

const logging = algoKitLogCaptureFixture()
beforeEach(logging.beforeEach)
Expand Down
2 changes: 1 addition & 1 deletion src/app.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { algoKitLogCaptureFixture, algorandFixture } from './testing'

describe('app', () => {
const localnet = algorandFixture()
beforeEach(localnet.beforeEach, 10_000)
beforeEach(localnet.newScope, 10_000)

const logging = algoKitLogCaptureFixture()
beforeEach(logging.beforeEach)
Expand Down
2 changes: 1 addition & 1 deletion src/indexer-lookup.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { AlgoAmount } from './types/amount'

describe('indexer-lookup', () => {
const localnet = algorandFixture()
beforeEach(localnet.beforeEach, 10_000)
beforeEach(localnet.newScope, 10_000)

const sendTestTransaction = async (amount?: AlgoAmount, from?: Address) => {
return await localnet.context.algorand.send.payment({
Expand Down
Loading
Loading