{"id":19841290,"url":"https://github.com/codelenny/irontest","last_synced_at":"2026-05-11T13:10:14.577Z","repository":{"id":44975799,"uuid":"204464775","full_name":"CodeLenny/irontest","owner":"CodeLenny","description":null,"archived":false,"fork":false,"pushed_at":"2023-01-04T08:16:42.000Z","size":354,"stargazers_count":0,"open_issues_count":13,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-28T22:28:19.236Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/CodeLenny.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-08-26T11:51:55.000Z","updated_at":"2019-08-26T11:52:14.000Z","dependencies_parsed_at":"2023-02-02T04:46:40.538Z","dependency_job_id":null,"html_url":"https://github.com/CodeLenny/irontest","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/CodeLenny/irontest","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CodeLenny%2Firontest","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CodeLenny%2Firontest/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CodeLenny%2Firontest/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CodeLenny%2Firontest/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/CodeLenny","download_url":"https://codeload.github.com/CodeLenny/irontest/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CodeLenny%2Firontest/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32896041,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-10T13:40:02.631Z","status":"online","status_checked_at":"2026-05-11T02:00:05.975Z","response_time":120,"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":[],"created_at":"2024-11-12T12:29:55.570Z","updated_at":"2026-05-11T13:10:14.541Z","avatar_url":"https://github.com/CodeLenny.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Iron Test\n\nA testing framework for TypeScript made specifically for tests that need to be run in a particular order.\n\nRoughly inspired by TestNG.\n\n## Usage\n\n### Defining Tests and Assertions\n\n```typescript\nimport { TestClass, Test, Asserts, Assert } from \"irontest\";\n\n@TestClass()\nexport class TestClass1 {\n    @Test()\n    public static firstTest(\n        @Asserts() assert: Assert,\n    ) {\n        assert.equal(42, 42);\n    }\n}\n```\n\n### Using async tests\n\n```typescript\nimport { TestClass, Test, Asserts, Assert } from \"irontest\";\nimport { resolve, map } from \"fluture\";\n\n@TestClass()\nexport class TestClass1 {\n    @Test()\n    public static returnPromise(\n        @Asserts() assert: Assert,\n    ): Promise\u003cboolean\u003e {\n        return Promise\n            .resolve(42)\n            .then(val =\u003e assert.equal(42, val))\n            .then(() =\u003e true);\n    }\n\n    @Test()\n    public static returnFuture(\n        @Asserts() assert: Assert,\n    ): Promise\u003cboolean\u003e {\n        const val = (resolve (42));\n        const checkVal = val =\u003e assert.equal(42, 42);\n        return (map (checkVal) (val));\n    }\n\n    /**\n     * Without `@TestReturnsAsync()`, any test depending on `outputPromise` would get the value '42'.\n     *\n     * With `@TestReturnsAsync()`, any test depending on `outputPromise` will get 'Promise\u003c42\u003e'.\n     */\n    @Test()\n    @TestReturnsAsync()\n    public static outputPromise() {\n        return Promise.resolve(42);\n    }\n}\n```\n\n### Other Options\n\n#### Test Timeouts\n\nSet the maximum duration for a test (defaults to 500ms):\n\n```typescript\nimport { TestClass, Test, TestTimeout } from \"irontest\";\n\n@TestClass()\nclass Tests {\n    @Test()\n    @TestTimeout(1000)\n    public static testWithTimeout() {\n        return new Promise((resolve, reject) =\u003e {\n            // This will fail the test due to the timeout:\n            setTimeout(() =\u003e resolve(), 2000);\n        })\n    }\n}\n```\n\n### Running\n\n```typescript\nimport { IronTest } from \"irontest\";\n\nimport { TestClass1 } from \"./testClass1\";\nimport { TestClass2 } from \"./testClass2\";\nimport { TestClass3 } from \"./testClass3\";\n\nconst runner = new IronTest();\nrunner.add([\n    TestClass1,\n    TestClass2.firstTest,\n    TestClass2.secondTest,\n    TestClass3.cleanup,\n]);\nrunner.run();\n```\n\n## Limitations\n\n### Limitation: Parallelization\n\nThere's many great options for running tests in parallel, like AVA.\nThis is not one of those.  Iron Test specializes in interdependent tests,\nlike complex flows in integration tests.\n\n### Limitation: Single Runtime Environment\n\nYou can't run the same tests (or tests with common dependencies) in different runs at the same time, in the same process.\n\n```typescript\n// Supported: Single run\nawait new IronTest().add([ TestClass1 ]).run().promise();\n\n// Supported: Two test groups with no common dependencies in parallel\nawait new IronTest().add([ TestClass1 ]).run().promise();\nawait new IronTest().add([ TestClass2 ]).run().promise();\n\n// Supported: Re-running tests after first run finishes\nawait new IronTest().add([ TestClass1 ]).run().promise();\nawait new IronTest().add([ TestClass1 ]).run().promise();\n\n// NOT SUPPORTED: running the same test in parallel\nimport { parallel } from \"fluture\";\nconst run1 = new IronTest().add([ TestClass1 ]).run();\nconst run2 = new IronTest().add([ TestClass1 ]).run();\nconst NOT_SUPPORTED = parallel (2, [ run1, run2 ]).promise();\n```\n\n### Limitation: Don't export 'TestClass'\n\n`TestClass` (the annotation used to mark classes containing tests)\nuses some... interesting... methods to get the path to the current test file.\n\nLong story short, it depends on being directly imported in your test file:\n\n```typescript\n// In `test/RobotController/no-robot-domination.ts`:\nimport { TestClass } from \"irontest\"; // or:\nimport { TestClass } from \"irontest/dist/src/decorators\"; // or:\nimport { TestClass } from \"irontest/dist/src/decorators/TestClass\";\n\n@TestClass()\nclass NoRobotDomination {\n    @Test()\n    public static robotKillsNobody() { /* ... */ }\n}\n\n// DON'T DO THIS:\n\n// In `test/helpers/this-wont-work.ts`:\nexport { TestClass } from \"irontest\";\n// In `test/RobotController/maybe-robot-domination.ts`:\nimport { TestClass } from \"../helpers/this-wont-work.ts\";\n// Now any tests will be marked as being inside 'this-wont-work.ts'\n// instead of 'maybe-robot-domination.ts'.\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodelenny%2Firontest","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcodelenny%2Firontest","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcodelenny%2Firontest/lists"}