effect icon indicating copy to clipboard operation
effect copied to clipboard

TestClock is rather slow

Open stevebluck opened this issue 8 months ago • 1 comments

What is the problem this feature would solve?

I am seeing quite large performance issues when using the TestClock in conjunction with property based tests. Here is a minimal example:

import { expect, it } from '@effect/vitest';
import { Effect, Schema, TestClock } from 'effect';

//   ✓ test 151ms
it.effect.prop('test', [Schema.Literal('test')], ([string]) =>
  Effect.gen(function* () {
    expect(string).toEqual('test');
  })
);

//   ✓ test  517ms
it.effect.prop('test', [Schema.Literal('test')], ([string]) =>
  Effect.gen(function* () {
    yield* TestClock.adjust(1);

    expect(string).toEqual('test');
  })
);

However in my real tests I am seeing a 10x difference. In this example the first test takes around 2 seconds and the second test takes over 20 seconds and the second test actually does less work but invokes TestClock.adjust:

it.effect.prop(
  'users can be idenitified by a token',
  [Email, Session.fields.token],
  Effect.fn(function* ([email, token]) {
    const users = yield* Users;

    const session = yield* users.register(email);
    const identified = yield* users.identify(session.token);

    expect(identified).toEqual(session);

    const noSuchToken = yield* Effect.exit(users.identify(token));
    expect(noSuchToken).toEqual(Exit.fail(new NoSuchToken()));
  }, Effect.provide(TestBench))
);

it.effect.prop(
  'users sessions can expire',
  [Email],
  Effect.fn(function* ([email]) {
    const users = yield* Users;

    const session = yield* users.register(email);

    yield* TestClock.adjust(Session.expiration);

    const noSuchToken = yield* Effect.exit(users.identify(session.token));
    expect(noSuchToken).toEqual(Exit.fail(new NoSuchToken()));
  }, Effect.provide(TestBench))
);

Vitest reporter:

 ❯ test/users/Users.test.ts (4 tests | 1 failed) 29190ms
   ❯ Users (3)
     ✓ users can register with unique emails  2294ms
     ✓ users can be idenitified by a token  2270ms
     × users sessions can expire 20041ms
   ✓ users receive a welcome email when they register  1214ms

What is the feature you are proposing to solve the problem?

Increase the speed of running tests.

What alternatives have you considered?

Decreasing the number of runs in the fastcheck config to help but it does not fix the underlying performance issue.

stevebluck avatar Apr 24 '25 10:04 stevebluck

Looks like in 4.0 this will get faster

Image

tim-smart avatar May 15 '25 02:05 tim-smart