npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@biorate/vitest

v1.9.0

Published

OOP test decorators for vitest with Allure support

Readme

@biorate/vitest

OOP test decorators for Vitest with Allure support.

Features

  • OOP Style: Write tests using classes and decorators
  • Allure Integration: Full support for Allure reporting
  • Clean Architecture: Modular design with separation of concerns
  • TypeScript: Full type safety
  • Scenario Pattern: Support for reusable test scenarios

Installation

pnpm i -D @biorate/vitest vitest allure-js-commons allure-vitest reflect-metadata

Usage

Basic Test

import { suite, test, expect } from '@biorate/vitest';
import 'reflect-metadata';

@suite('My Test Suite')
class MyTest {
  @test('should pass')
  async shouldPass() {
    expect(1 + 1).toBe(2);
  }
}

Allure Annotations

import { 
  suite, 
  test, 
  epic, 
  feature, 
  story, 
  severity, 
  owner,
  label,
  tags,
  issue,
  description,
} from '@biorate/vitest';
import { Severity } from 'allure-js-commons';

@suite('Authentication')
class AuthTest {
  @epic('Security')
  @feature('Login')
  @story('User Authentication')
  @severity(Severity.CRITICAL)
  @owner('user-id-123')
  @tags('auth', 'login')
  @label('priority', 'high')
  @issue('JIRA-123', 'https://jira.example.com/JIRA-123')
  @description('Tests user login functionality')
  @test('should login user')
  async shouldLoginUser() {
    // test implementation
  }
}

Lifecycle Hooks

@suite('Database Tests')
class DatabaseTest {
  protected static async beforeAll() {
    // Setup before all tests
  }

  protected static async afterAll() {
    // Cleanup after all tests
  }

  protected async before() {
    // Setup before each test
  }

  protected async after() {
    // Cleanup after each test
  }

  @test('should connect')
  async shouldConnect() {
    // test implementation
  }
}

Test Modifiers

import { suite, test, skip, only, todo, timeout, repeats } from '@biorate/vitest';

@suite('Edge Cases')
class EdgeCasesTest {
  @skip()
  @test('skip this test')
  async skippedTest() {
    // will be skipped
  }

  @only()
  @test('run only this test')
  async exclusiveTest() {
    // only this test will run in the suite
  }

  @todo()
  @test('todo test')
  async todoTest() {
    // marked as todo
  }

  @timeout(5000)
  @test('test with timeout')
  async timeoutTest() {
    // will timeout after 5 seconds
  }

  @repeats(3, { mode: 'series' })
  @test('flaky test')
  async flakyTest() {
    // will run 3 times in series
  }
}

Scenario Pattern

import { Scenario, Step, Context } from '@biorate/vitest';

export class LoginScenario extends Scenario {
  @Step('Open login page')
  protected async openLoginPage() {
    await this.context.page.goto('/login');
  }

  @Step('Enter credentials')
  protected async enterCredentials() {
    await this.context.page.fill('#username', 'user');
    await this.context.page.fill('#password', 'pass');
  }

  @Step('Submit form')
  protected async submitForm() {
    await this.context.page.click('button[type=submit]');
  }
}

// Usage in test
@suite('Login Flow')
class LoginTest {
  @test('should login successfully')
  async testLogin() {
    await Context.run([LoginScenario], { 
      page: this.page 
    });
  }
}

Suite Options

import { suite, test } from '@biorate/vitest';

@suite('Serial Suite', { mode: 'serial' })
class SerialTest {
  @test('test 1')
  async test1() {
    // tests will run sequentially
  }

  @test('test 2')
  async test2() {}
}

@suite('Parallel Suite', { mode: 'parallel' })
class ParallelTest {
  @test('test 1')
  async test1() {
    // tests will run in parallel
  }

  @test('test 2')
  async test2() {}
}

@suite('Suite with Timeout', { timeout: 10000 })
class TimeoutTest {
  @test('test with suite timeout')
  async test1() {
    // suite has 10 second timeout
  }
}

@suite('Suite with Retries', { retries: 2 })
class RetryTest {
  @test('flaky test')
  async test1() {
    // will retry up to 2 times on failure
  }
}

@suite('Full Options', { 
  mode: 'serial', 
  timeout: 10000, 
  retries: 2 
})
class FullOptionsTest {
  @test('test')
  async test() {}
}

@test('test 1') async test1() {}

@test('test 2') async test2() {} }


## Migration from Mocha

For smooth migration from `@biorate/mocha` to `@biorate/vitest`, we provide deprecated decorators that maintain backward compatibility.

### Deprecated Decorators

The following decorators are available for Mocha compatibility but are **deprecated**. Use the recommended alternatives:

| Deprecated Decorator | Recommended Alternative | Description |
|---------------------|------------------------|-------------|
| `@retries(n)` | `@repeats(n, { mode: 'series' })` | Retry failed tests |
| `@parallel(true)` | `@suite('name', { mode: 'parallel' })` | Enable parallel execution |
| `@slow(ms)` | `@timeout(ms)` | Mark slow tests |
| `@pending()` | `@skip()` or `@todo()` | Mark test as pending |
| `@params(...)` | Use Vitest's native parameterized tests | Parameterized tests |
| `context` (symbol) | Use Vitest's test context directly | Test context symbol |
| `@allureStep(name)` | Use `allure.step()` directly | Allure step decorator |
| `@attachment(name, content, type)` | Use `allure.attachment()` directly | Allure attachment decorator |
| `@testCaseId(id)` | `@id(id)` | Test case ID decorator |
| `@data(params, name?)` | Use Vitest's native parameterized tests | Parameterized test data |
| `decorate(instance)` | Use Allure API directly | Decorate Allure instance |
| `assignPmsUrl(url)` | Use environment variables | Assign PMS URL |
| `assignTmsUrl(url)` | Use environment variables | Assign TMS URL |

### Deprecation Warnings

When using deprecated decorators, you will see a warning message in the console **once per decorator type**:

[@biorate/vitest] Deprecated decorator: @retries. Use @repeats(count, { mode: "series" }) instead.


This helps you identify which decorators need to be updated during migration.

### Migration Example

**Before (Mocha):**
```typescript
import { suite, parallel, retries, test } from '@biorate/mocha';

@suite
@parallel(true)
class MyTest {
  @retries(2)
  @test('should work')
  async myTest() {
    // test implementation
  }
}

After (Vitest):

import { suite, repeats, test } from '@biorate/vitest';

@suite('My Test', { mode: 'parallel', retries: 2 })
class MyTest {
  @test('should work')
  async myTest() {
    // test implementation
  }
}

Compatibility Mode

You can still use deprecated decorators during migration:

import { suite, parallel, retries, test } from '@biorate/vitest';

@suite('My Test')
@parallel(true) // deprecated, but works
class MyTest {
  @retries(2) // deprecated, but works
  @test('should work')
  async myTest() {
    // test implementation
  }
}

Note: Deprecated decorators will be removed in future versions. Please update your code to use the recommended alternatives.

API Reference

Decorators

Test Definition

  • @suite(name?, options?) - Define a test suite class
  • @test(name?) - Define a test method

Modifiers

  • @skip() - Skip test/suite
  • @only() - Run only this test/suite
  • @todo() - Mark as TODO
  • @timeout(ms) - Set timeout
  • @repeats(count, options) - Repeat test

Allure

  • @epic(name) - Set epic
  • @feature(name) - Set feature
  • @story(name) - Set story
  • @severity(level) - Set severity
  • @owner(name) - Set owner
  • @tag(tag) - Add single tag
  • @tags(...tags) - Add multiple tags
  • @label(name, value) - Add custom label
  • @link(url, name?, type?) - Add link
  • @id(id) - Set test ID
  • @allureSuite(name) - Set Allure suite
  • @parentSuite(name) - Set parent suite
  • @subSuite(name) - Set sub suite
  • @issue(name, url?) - Add issue link
  • @description(value) - Add description

Vitest Configuration

Create vitest.config.ts:

import { defineConfig } from 'vitest/config';

export default defineConfig({
  test: {
    reporter: [
      'default',
      ['allure-vitest', { outputFolder: 'allure-results' }],
    ],
  },
});

License

MIT