feat(tstest): Enhance tstest with fluent API, suite grouping, tag filtering, fixture & snapshot testing, and parallel execution improvements
This commit is contained in:
3
test/debug.js
Normal file
3
test/debug.js
Normal file
@ -0,0 +1,3 @@
|
||||
// Direct run to see TAP output
|
||||
const { execSync } = require('child_process');
|
||||
console.log(execSync('tsx test/tapbundle/test.debug.ts', { cwd: '/mnt/data/lossless/git.zone/tstest' }).toString());
|
@ -45,4 +45,11 @@ const test6 = tap.skip.test('my 6th test -> should fail after 1000ms', async (to
|
||||
await tools.delayFor(100);
|
||||
});
|
||||
|
||||
await tap.start();
|
||||
const testPromise = tap.start();
|
||||
|
||||
// Export promise for browser compatibility
|
||||
if (typeof globalThis !== 'undefined') {
|
||||
(globalThis as any).tapPromise = testPromise;
|
||||
}
|
||||
|
||||
export default testPromise;
|
19
test/tapbundle/test.debug.ts
Normal file
19
test/tapbundle/test.debug.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import { tap, expect } from '../../ts_tapbundle/index.js';
|
||||
|
||||
// Simple test to debug TAP output
|
||||
tap.test('test 1', async () => {
|
||||
console.log('Test 1 running');
|
||||
expect(true).toBeTrue();
|
||||
});
|
||||
|
||||
tap.test('test 2 - skip', async (toolsArg) => {
|
||||
toolsArg.skip('Skipping test 2');
|
||||
expect(false).toBeTrue();
|
||||
});
|
||||
|
||||
tap.test('test 3', async () => {
|
||||
console.log('Test 3 running');
|
||||
expect(true).toBeTrue();
|
||||
});
|
||||
|
||||
tap.start();
|
101
test/tapbundle/test.describe.ts
Normal file
101
test/tapbundle/test.describe.ts
Normal file
@ -0,0 +1,101 @@
|
||||
import { tap, expect } from '../../ts_tapbundle/index.js';
|
||||
|
||||
// Global state for testing lifecycle hooks
|
||||
const lifecycleOrder: string[] = [];
|
||||
|
||||
tap.describe('Test Suite A', () => {
|
||||
tap.beforeEach(async (toolsArg) => {
|
||||
lifecycleOrder.push('Suite A - beforeEach');
|
||||
});
|
||||
|
||||
tap.afterEach(async (toolsArg) => {
|
||||
lifecycleOrder.push('Suite A - afterEach');
|
||||
});
|
||||
|
||||
tap.test('test 1 in suite A', async (toolsArg) => {
|
||||
lifecycleOrder.push('Test 1');
|
||||
expect(true).toBeTrue();
|
||||
});
|
||||
|
||||
tap.test('test 2 in suite A', async (toolsArg) => {
|
||||
lifecycleOrder.push('Test 2');
|
||||
expect(true).toBeTrue();
|
||||
});
|
||||
|
||||
tap.describe('Nested Suite B', () => {
|
||||
tap.beforeEach(async (toolsArg) => {
|
||||
lifecycleOrder.push('Suite B - beforeEach');
|
||||
});
|
||||
|
||||
tap.afterEach(async (toolsArg) => {
|
||||
lifecycleOrder.push('Suite B - afterEach');
|
||||
});
|
||||
|
||||
tap.test('test 1 in nested suite B', async (toolsArg) => {
|
||||
lifecycleOrder.push('Nested Test 1');
|
||||
expect(true).toBeTrue();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Test outside any suite
|
||||
tap.test('test outside suites', async (toolsArg) => {
|
||||
lifecycleOrder.push('Outside Test');
|
||||
expect(true).toBeTrue();
|
||||
});
|
||||
|
||||
tap.describe('Test Suite with errors', () => {
|
||||
tap.beforeEach(async (toolsArg) => {
|
||||
// Setup that might fail
|
||||
const data = await Promise.resolve({ value: 42 });
|
||||
toolsArg.testData = data;
|
||||
});
|
||||
|
||||
tap.test('test with error', async (toolsArg) => {
|
||||
// Verify that data from beforeEach is available
|
||||
expect(toolsArg.testData).toBeDefined();
|
||||
expect(toolsArg.testData.value).toEqual(42);
|
||||
|
||||
// Test that error handling works by catching an error
|
||||
try {
|
||||
throw new Error('Intentional error');
|
||||
} catch (error) {
|
||||
expect(error.message).toEqual('Intentional error');
|
||||
}
|
||||
});
|
||||
|
||||
tap.test('test with skip in suite', async (toolsArg) => {
|
||||
toolsArg.skip('Skipping this test in a suite');
|
||||
expect(false).toBeTrue();
|
||||
});
|
||||
});
|
||||
|
||||
// Verify lifecycle order - this test runs last to check if all hooks were called properly
|
||||
tap.test('verify lifecycle hook order', async (toolsArg) => {
|
||||
// Wait a bit to ensure all tests have completed
|
||||
await new Promise(resolve => setTimeout(resolve, 50));
|
||||
console.log('Lifecycle order:', lifecycleOrder);
|
||||
|
||||
// Check that the tests we expect to have run actually did
|
||||
expect(lifecycleOrder).toContain('Test 1');
|
||||
expect(lifecycleOrder).toContain('Test 2');
|
||||
expect(lifecycleOrder).toContain('Nested Test 1');
|
||||
|
||||
// Check that beforeEach was called before each test in Suite A
|
||||
const test1Index = lifecycleOrder.indexOf('Test 1');
|
||||
expect(test1Index).toBeGreaterThan(-1);
|
||||
const beforeTest1 = lifecycleOrder.slice(0, test1Index);
|
||||
expect(beforeTest1).toContain('Suite A - beforeEach');
|
||||
|
||||
// Check that afterEach was called after test 1
|
||||
const afterTest1 = lifecycleOrder.slice(test1Index + 1);
|
||||
expect(afterTest1).toContain('Suite A - afterEach');
|
||||
|
||||
// Check nested suite lifecycle
|
||||
const nestedTest1Index = lifecycleOrder.indexOf('Nested Test 1');
|
||||
expect(nestedTest1Index).toBeGreaterThan(-1);
|
||||
const beforeNestedTest1 = lifecycleOrder.slice(0, nestedTest1Index);
|
||||
expect(beforeNestedTest1).toContain('Suite B - beforeEach');
|
||||
});
|
||||
|
||||
tap.start();
|
120
test/tapbundle/test.fixtures.ts
Normal file
120
test/tapbundle/test.fixtures.ts
Normal file
@ -0,0 +1,120 @@
|
||||
import { tap, TapTools } from '../../ts_tapbundle/index.js';
|
||||
import { expect } from '@push.rocks/smartexpect';
|
||||
|
||||
// Define fixture factories
|
||||
interface User {
|
||||
id: number;
|
||||
name: string;
|
||||
email: string;
|
||||
role: string;
|
||||
}
|
||||
|
||||
interface Post {
|
||||
id: number;
|
||||
title: string;
|
||||
content: string;
|
||||
authorId: number;
|
||||
tags: string[];
|
||||
}
|
||||
|
||||
// Define user fixture factory
|
||||
TapTools.defineFixture<User>('user', (data) => {
|
||||
const id = data?.id || Math.floor(Math.random() * 10000);
|
||||
return {
|
||||
id,
|
||||
name: data?.name || `Test User ${id}`,
|
||||
email: data?.email || `user${id}@test.com`,
|
||||
role: data?.role || 'user'
|
||||
};
|
||||
});
|
||||
|
||||
// Define post fixture factory
|
||||
TapTools.defineFixture<Post>('post', async (data) => {
|
||||
const id = data?.id || Math.floor(Math.random() * 10000);
|
||||
return {
|
||||
id,
|
||||
title: data?.title || `Post ${id}`,
|
||||
content: data?.content || `Content for post ${id}`,
|
||||
authorId: data?.authorId || 1,
|
||||
tags: data?.tags || ['test', 'sample']
|
||||
};
|
||||
});
|
||||
|
||||
tap.describe('Fixture System', () => {
|
||||
tap.afterEach(async () => {
|
||||
// Clean up fixtures after each test
|
||||
await TapTools.cleanupFixtures();
|
||||
});
|
||||
|
||||
tap.tags('unit', 'fixtures')
|
||||
.test('should create a simple fixture', async (toolsArg) => {
|
||||
const user = await toolsArg.fixture<User>('user');
|
||||
|
||||
expect(user).toHaveProperty('id');
|
||||
expect(user).toHaveProperty('name');
|
||||
expect(user).toHaveProperty('email');
|
||||
expect(user.role).toEqual('user');
|
||||
});
|
||||
|
||||
tap.tags('unit', 'fixtures')
|
||||
.test('should create fixture with custom data', async (toolsArg) => {
|
||||
const admin = await toolsArg.fixture<User>('user', {
|
||||
name: 'Admin User',
|
||||
role: 'admin'
|
||||
});
|
||||
|
||||
expect(admin.name).toEqual('Admin User');
|
||||
expect(admin.role).toEqual('admin');
|
||||
expect(admin.email).toContain('@test.com');
|
||||
});
|
||||
|
||||
tap.tags('unit', 'fixtures')
|
||||
.test('should create multiple fixtures with factory', async (toolsArg) => {
|
||||
const userFactory = toolsArg.factory<User>('user');
|
||||
const users = await userFactory.createMany(3);
|
||||
|
||||
// Try different approach
|
||||
expect(users.length).toEqual(3);
|
||||
expect(users[0].id).not.toEqual(users[1].id);
|
||||
expect(users[0].email).not.toEqual(users[1].email);
|
||||
});
|
||||
|
||||
tap.tags('unit', 'fixtures')
|
||||
.test('should create fixtures with custom data per instance', async (toolsArg) => {
|
||||
const postFactory = toolsArg.factory<Post>('post');
|
||||
const posts = await postFactory.createMany(3, (index) => ({
|
||||
title: `Post ${index + 1}`,
|
||||
tags: [`tag${index + 1}`]
|
||||
}));
|
||||
|
||||
expect(posts[0].title).toEqual('Post 1');
|
||||
expect(posts[1].title).toEqual('Post 2');
|
||||
expect(posts[2].title).toEqual('Post 3');
|
||||
|
||||
expect(posts[0].tags).toContain('tag1');
|
||||
expect(posts[1].tags).toContain('tag2');
|
||||
});
|
||||
|
||||
tap.tags('unit', 'fixtures')
|
||||
.test('should handle related fixtures', async (toolsArg) => {
|
||||
const user = await toolsArg.fixture<User>('user', { name: 'Author' });
|
||||
const post = await toolsArg.fixture<Post>('post', {
|
||||
title: 'My Article',
|
||||
authorId: user.id
|
||||
});
|
||||
|
||||
expect(post.authorId).toEqual(user.id);
|
||||
});
|
||||
|
||||
tap.tags('unit', 'fixtures', 'error')
|
||||
.test('should throw error for undefined fixture', async (toolsArg) => {
|
||||
try {
|
||||
await toolsArg.fixture('nonexistent');
|
||||
expect(true).toBeFalse(); // Should not reach here
|
||||
} catch (error: any) {
|
||||
expect(error.message).toContain('Fixture \'nonexistent\' not found');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
tap.start();
|
32
test/tapbundle/test.fluent-syntax.ts
Normal file
32
test/tapbundle/test.fluent-syntax.ts
Normal file
@ -0,0 +1,32 @@
|
||||
import { tap, expect } from '../../ts_tapbundle/index.js';
|
||||
|
||||
// Test with fluent syntax
|
||||
tap.tags('unit', 'fluent')
|
||||
.priority('high')
|
||||
.test('test with fluent syntax', async (toolsArg) => {
|
||||
expect(true).toBeTrue();
|
||||
toolsArg.context.set('fluentTest', 'works');
|
||||
});
|
||||
|
||||
// Chain multiple settings
|
||||
tap.tags('integration')
|
||||
.priority('low')
|
||||
.retry(3)
|
||||
.timeout(5000)
|
||||
.test('test with multiple settings', async (toolsArg) => {
|
||||
expect(true).toBeTrue();
|
||||
});
|
||||
|
||||
// Test context access from fluent test
|
||||
tap.tags('unit')
|
||||
.test('verify fluent context', async (toolsArg) => {
|
||||
const fluentValue = toolsArg.context.get('fluentTest');
|
||||
expect(fluentValue).toEqual('works');
|
||||
});
|
||||
|
||||
// Test without tags - should show all tests run without filtering
|
||||
tap.test('regular test without tags', async (toolsArg) => {
|
||||
expect(true).toBeTrue();
|
||||
});
|
||||
|
||||
tap.start();
|
52
test/tapbundle/test.snapshot.ts
Normal file
52
test/tapbundle/test.snapshot.ts
Normal file
@ -0,0 +1,52 @@
|
||||
import { tap, expect } from '../../ts_tapbundle/index.js';
|
||||
|
||||
// Test basic snapshot functionality
|
||||
tap.tags('unit', 'snapshot')
|
||||
.test('should match string snapshot', async (toolsArg) => {
|
||||
const testString = 'Hello, World!';
|
||||
await toolsArg.matchSnapshot(testString);
|
||||
});
|
||||
|
||||
// Test object snapshot
|
||||
tap.tags('unit', 'snapshot')
|
||||
.test('should match object snapshot', async (toolsArg) => {
|
||||
const testObject = {
|
||||
name: 'Test User',
|
||||
age: 30,
|
||||
hobbies: ['reading', 'coding', 'gaming'],
|
||||
metadata: {
|
||||
created: '2024-01-01',
|
||||
updated: '2024-01-15'
|
||||
}
|
||||
};
|
||||
await toolsArg.matchSnapshot(testObject);
|
||||
});
|
||||
|
||||
// Test named snapshots
|
||||
tap.tags('unit', 'snapshot')
|
||||
.test('should handle multiple named snapshots', async (toolsArg) => {
|
||||
const config1 = { version: '1.0.0', features: ['a', 'b'] };
|
||||
const config2 = { version: '2.0.0', features: ['a', 'b', 'c'] };
|
||||
|
||||
await toolsArg.matchSnapshot(config1, 'config_v1');
|
||||
await toolsArg.matchSnapshot(config2, 'config_v2');
|
||||
});
|
||||
|
||||
// Test dynamic content with snapshot
|
||||
tap.tags('unit', 'snapshot')
|
||||
.test('should handle template snapshot', async (toolsArg) => {
|
||||
const template = `
|
||||
<div class="container">
|
||||
<h1>Welcome</h1>
|
||||
<p>This is a test template</p>
|
||||
<ul>
|
||||
<li>Item 1</li>
|
||||
<li>Item 2</li>
|
||||
</ul>
|
||||
</div>
|
||||
`.trim();
|
||||
|
||||
await toolsArg.matchSnapshot(template, 'html_template');
|
||||
});
|
||||
|
||||
tap.start();
|
49
test/tapbundle/test.tags-context.ts
Normal file
49
test/tapbundle/test.tags-context.ts
Normal file
@ -0,0 +1,49 @@
|
||||
import { tap, expect } from '../../ts_tapbundle/index.js';
|
||||
|
||||
// First test sets some data and has tags
|
||||
tap.tags('unit', 'context')
|
||||
.priority('high')
|
||||
.test('test with tags and context setting', async (toolsArg) => {
|
||||
// Set some data in context
|
||||
toolsArg.context.set('testData', { value: 42 });
|
||||
toolsArg.context.set('users', ['alice', 'bob']);
|
||||
|
||||
expect(true).toBeTrue();
|
||||
});
|
||||
|
||||
// Second test reads the context data
|
||||
tap.tags('unit', 'context')
|
||||
.test('test reading context', async (toolsArg) => {
|
||||
// Read data from context
|
||||
const testData = toolsArg.context.get('testData');
|
||||
const users = toolsArg.context.get('users');
|
||||
|
||||
expect(testData).toEqual({ value: 42 });
|
||||
expect(users).toContain('alice');
|
||||
expect(users).toContain('bob');
|
||||
});
|
||||
|
||||
// Test without tags - should be skipped when filtering by tags
|
||||
tap.test('test without tags', async (toolsArg) => {
|
||||
expect(true).toBeTrue();
|
||||
});
|
||||
|
||||
// Test with different tags
|
||||
tap.tags('integration')
|
||||
.priority('low')
|
||||
.test('integration test', async (toolsArg) => {
|
||||
expect(true).toBeTrue();
|
||||
});
|
||||
|
||||
// Test context cleanup
|
||||
tap.tags('unit')
|
||||
.test('test context operations', async (toolsArg) => {
|
||||
// Set and delete
|
||||
toolsArg.context.set('temp', 'value');
|
||||
expect(toolsArg.context.get('temp')).toEqual('value');
|
||||
|
||||
toolsArg.context.delete('temp');
|
||||
expect(toolsArg.context.get('temp')).toBeUndefined();
|
||||
});
|
||||
|
||||
tap.start();
|
85
test/tapbundle/test.toolsarg.ts
Normal file
85
test/tapbundle/test.toolsarg.ts
Normal file
@ -0,0 +1,85 @@
|
||||
import { tap, expect } from '../../ts_tapbundle/index.js';
|
||||
|
||||
// Test skip functionality
|
||||
tap.test('should skip a test with skip()', async (toolsArg) => {
|
||||
toolsArg.skip('This test is skipped');
|
||||
// This code should not run
|
||||
expect(false).toBeTrue();
|
||||
});
|
||||
|
||||
tap.test('should conditionally skip with skipIf()', async (toolsArg) => {
|
||||
const shouldSkip = true;
|
||||
toolsArg.skipIf(shouldSkip, 'Condition met, skipping');
|
||||
// This code should not run
|
||||
expect(false).toBeTrue();
|
||||
});
|
||||
|
||||
tap.test('should not skip when skipIf condition is false', async (toolsArg) => {
|
||||
const shouldSkip = false;
|
||||
toolsArg.skipIf(shouldSkip, 'Should not skip');
|
||||
// This code should run
|
||||
expect(true).toBeTrue();
|
||||
});
|
||||
|
||||
// Test todo functionality
|
||||
tap.test('should mark test as todo', async (toolsArg) => {
|
||||
toolsArg.todo('Not implemented yet');
|
||||
// Test code that would be implemented later
|
||||
expect(true).toBeTrue();
|
||||
});
|
||||
|
||||
// Test timeout functionality
|
||||
tap.test('should set custom timeout', async (toolsArg) => {
|
||||
toolsArg.timeout(5000);
|
||||
// Simulate a task that takes 100ms
|
||||
await toolsArg.delayFor(100);
|
||||
expect(true).toBeTrue();
|
||||
});
|
||||
|
||||
// This test is expected to fail due to timeout
|
||||
tap.test('should timeout when exceeding limit', async (toolsArg) => {
|
||||
toolsArg.timeout(100);
|
||||
// This test will timeout and be marked as failed by the test runner
|
||||
await toolsArg.delayFor(2000);
|
||||
// This line should not be reached due to timeout
|
||||
});
|
||||
|
||||
tap.test('timeout should work properly', async (toolsArg) => {
|
||||
toolsArg.timeout(200);
|
||||
// This test should complete successfully within the timeout
|
||||
await toolsArg.delayFor(50);
|
||||
expect(true).toBeTrue();
|
||||
});
|
||||
|
||||
// Test retry functionality
|
||||
tap.retry(3)
|
||||
.test('should retry on failure', async (toolsArg) => {
|
||||
// Use retry count to determine success
|
||||
const currentRetry = toolsArg.retryCount;
|
||||
|
||||
// Fail on first two attempts (0 and 1), succeed on third (2)
|
||||
if (currentRetry < 2) {
|
||||
throw new Error(`Attempt ${currentRetry + 1} failed`);
|
||||
}
|
||||
|
||||
expect(currentRetry).toEqual(2);
|
||||
});
|
||||
|
||||
tap.test('should expose retry count', async (toolsArg) => {
|
||||
toolsArg.retry(2);
|
||||
|
||||
// The retry count should be available
|
||||
expect(toolsArg.retryCount).toBeLessThanOrEqual(2);
|
||||
expect(true).toBeTrue();
|
||||
});
|
||||
|
||||
// Test allowFailure
|
||||
tap.test('should allow failure', async (toolsArg) => {
|
||||
// Just verify that allowFailure() can be called without throwing
|
||||
toolsArg.allowFailure();
|
||||
expect(true).toBeTrue();
|
||||
// Note: In a real implementation, we would see "please note: failure allowed!"
|
||||
// in the output when this test fails, but the test itself will still be marked as failed
|
||||
});
|
||||
|
||||
tap.start();
|
@ -17,9 +17,9 @@ const test3 = tap.test(
|
||||
async () => {
|
||||
expect(
|
||||
(await test1.testPromise).hrtMeasurement.milliSeconds <
|
||||
(await test2).hrtMeasurement.milliSeconds,
|
||||
(await test2.testPromise).hrtMeasurement.milliSeconds,
|
||||
).toBeTrue();
|
||||
expect((await test2.testPromise).hrtMeasurement.milliSeconds > 1000).toBeTrue();
|
||||
expect((await test2.testPromise).hrtMeasurement.milliSeconds >= 1000).toBeTrue();
|
||||
},
|
||||
);
|
||||
|
||||
@ -46,4 +46,4 @@ const test7 = tap.test('my 7th test -> should print a colored string', async (to
|
||||
console.log(cs);
|
||||
});
|
||||
|
||||
tap.start();
|
||||
tap.start();
|
16
test/tstest/test-parallel-demo.ts
Normal file
16
test/tstest/test-parallel-demo.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import { tap, expect } from '../../ts_tapbundle/index.js';
|
||||
import * as fs from 'fs';
|
||||
|
||||
// Test to demonstrate parallel execution timing - run with glob pattern
|
||||
// This will give us a clear view of execution order with timestamps
|
||||
|
||||
const timestamp = () => new Date().toISOString().substr(11, 12);
|
||||
|
||||
tap.test('demo test in main file', async (toolsArg) => {
|
||||
console.log(`[${timestamp()}] Test parallel demo started`);
|
||||
await toolsArg.delayFor(1000);
|
||||
console.log(`[${timestamp()}] Test parallel demo completed`);
|
||||
expect(true).toBeTrue();
|
||||
});
|
||||
|
||||
tap.start();
|
11
test/tstest/test.api.para__2.ts
Normal file
11
test/tstest/test.api.para__2.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { tap, expect } from '../../ts_tapbundle/index.js';
|
||||
|
||||
// This test runs in parallel group 2
|
||||
tap.test('api test in parallel group 2', async (toolsArg) => {
|
||||
console.log('API test started');
|
||||
await toolsArg.delayFor(800);
|
||||
console.log('API test completed');
|
||||
expect(true).toBeTrue();
|
||||
});
|
||||
|
||||
tap.start();
|
13
test/tstest/test.auth.para__1.ts
Normal file
13
test/tstest/test.auth.para__1.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import { tap, expect } from '../../ts_tapbundle/index.js';
|
||||
|
||||
// This test runs in parallel group 1
|
||||
const timestamp = () => new Date().toISOString().substr(11, 12);
|
||||
|
||||
tap.test('auth test in parallel group 1', async (toolsArg) => {
|
||||
console.log(`[${timestamp()}] Auth test started`);
|
||||
await toolsArg.delayFor(1000);
|
||||
console.log(`[${timestamp()}] Auth test completed`);
|
||||
expect(true).toBeTrue();
|
||||
});
|
||||
|
||||
tap.start();
|
11
test/tstest/test.db.para__2.ts
Normal file
11
test/tstest/test.db.para__2.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { tap, expect } from '../../ts_tapbundle/index.js';
|
||||
|
||||
// This test runs in parallel group 2
|
||||
tap.test('db test in parallel group 2', async (toolsArg) => {
|
||||
console.log('DB test started');
|
||||
await toolsArg.delayFor(800);
|
||||
console.log('DB test completed');
|
||||
expect(true).toBeTrue();
|
||||
});
|
||||
|
||||
tap.start();
|
10
test/tstest/test.serial1.ts
Normal file
10
test/tstest/test.serial1.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import { tap, expect } from '../../ts_tapbundle/index.js';
|
||||
|
||||
// This test runs serially (no para__ in filename)
|
||||
tap.test('serial test 1', async (toolsArg) => {
|
||||
await toolsArg.delayFor(500);
|
||||
console.log('Serial test 1 completed');
|
||||
expect(true).toBeTrue();
|
||||
});
|
||||
|
||||
tap.start();
|
10
test/tstest/test.serial2.ts
Normal file
10
test/tstest/test.serial2.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import { tap, expect } from '../../ts_tapbundle/index.js';
|
||||
|
||||
// This test runs serially (no para__ in filename)
|
||||
tap.test('serial test 2', async (toolsArg) => {
|
||||
await toolsArg.delayFor(500);
|
||||
console.log('Serial test 2 completed');
|
||||
expect(true).toBeTrue();
|
||||
});
|
||||
|
||||
tap.start();
|
13
test/tstest/test.user.para__1.ts
Normal file
13
test/tstest/test.user.para__1.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import { tap, expect } from '../../ts_tapbundle/index.js';
|
||||
|
||||
// This test runs in parallel group 1
|
||||
const timestamp = () => new Date().toISOString().substr(11, 12);
|
||||
|
||||
tap.test('user test in parallel group 1', async (toolsArg) => {
|
||||
console.log(`[${timestamp()}] User test started`);
|
||||
await toolsArg.delayFor(1000);
|
||||
console.log(`[${timestamp()}] User test completed`);
|
||||
expect(true).toBeTrue();
|
||||
});
|
||||
|
||||
tap.start();
|
Reference in New Issue
Block a user