This project now supports a dev-only Classic ASP test harness built with aspunit.
public/tests/tests/aspunit/The tests/ IIS application assumes the repository layout keeps tests/, public/, core/, and app/ as sibling directories.
| Type | Path | Purpose |
|---|---|---|
| Create | tests/web.config |
IIS/default-document config for the isolated test app |
| Create | tests/unit/web.config |
Mirrored config for nested unit pages that load config-aware code |
| Create | tests/component/web.config |
Mirrored config for nested component pages that load config-aware code |
| Create | tests/integration/web.config |
Mirrored config for nested integration pages that load config-aware code |
| Create | tests/sync-webconfigs.vbs |
Utility script to mirror tests/web.config into nested test folders |
| Create | tests/run-tests.cmd |
Windows helper to sync configs and open the test runner URL |
| Create | tests/bootstrap.asp |
Shared test bootstrap and runtime reset helpers |
| Create | tests/PlainRunnerTheme.asp |
Local runner theme that removes CDN dependence from the test UI |
| Create | tests/support/HttpCaptureHelpers.asp |
Shared HTTP capture helpers for rendered-page assertions |
| Create | tests/test-manifest.asp |
Single source of truth for registered test pages |
| Create | tests/run-all.asp |
Browser runner that aggregates all test pages |
| Vendor | tests/aspunit/Lib/* |
Upstream aspunit framework files |
| Vendor | tests/aspunit/LICENSE-MIT |
Upstream aspunit license for vendored third-party code |
| Create | tests/unit/TestHelpers.asp |
Deterministic helper-function unit tests |
| Create | tests/unit/TestControllerRegistry.asp |
Controller whitelist/format unit tests |
| Create | tests/component/TestHomeController.asp |
Controlled component-level controller test |
| Create | tests/integration/TestMvcDispatch.asp |
Narrow router/dispatch smoke test |
| Create | tests/integration/TestRoutes.asp |
Route-helper/config integration coverage |
| Create | tests/integration/TestConfigSettings.asp |
Nested config and fallback behavior coverage |
| Create | tests/integration/TestRenderedOutput.asp |
Production-page output assertions through safe HTTP capture |
| Create | tests/integration/TestSharedLayout.asp |
Shared header/footer/layout assertions against rendered production pages |
| Reference | public/web.config |
Source of mirrored config keys for the test app |
| Reference | core/helpers.asp |
Helper functions and config-loading behavior under test |
| Reference | core/mvc.asp |
Dispatcher behavior used by the smoke test |
| Reference | core/lib.ControllerRegistry.asp |
Whitelist behavior under test |
| Verify | public/ site |
Confirm production app exposes no test routes/pages |
applicationhost.config (quickest)This repo ships an applicationhost.config (used by run_site.cmd) that defines two IIS Express sites:
Development Web Site - public/ on http://localhost:8080/Tests Web Site - tests/ on http://localhost:8081/<asp enableParentPaths="true" .../> is set server-wide in that same file - this is what lets tests/bootstrap.asp and the integration pages #include sibling files from ../core/ and ../app/ (physically outside the tests/ site's own root). No per-app IIS configuration is required.
A single iisexpress.exe process only ever runs one site from a config file - per iisexpress /?: “/config:config-file ... runs the first site in the specified configuration file.” serverAutoStart="true" is an IIS/W3SVC (full IIS) concept and is not honored by a standalone iisexpress.exe invocation, so listing a second <site> is not enough on its own.
run_site.cmd - it launches two iisexpress.exe processes, each pinned to one site with /site:"..." (each opens its own console window so you can see that site's request log).http://localhost:8081/ (or run tests\run-tests.cmd, which syncs configs first, then opens the runner URL).tests/web.config's ProductionAppBaseUrl is set to http://localhost:8080/ to match the production site's actual binding above - TestRenderedOutput.asp/TestSharedLayout.asp use this to fetch real rendered pages over HTTP. If you rebind either site to a different port, update this value too, update the matching /site:/binding in applicationhost.config and run_site.cmd, and re-run the sync script (step 5 below).If applicationhost.config only has the Development Web Site entry (e.g. in a checkout from before the Tests Web Site entry was added), that's why the tests app has nothing to browse to - add a second <site> block for tests/ following the same shape as the existing one, on its own port.
public/.tests/.tests/ app - in IIS Manager this is the “Enable Parent Paths” checkbox under ASP settings for that application (or <system.webServer><asp enableParentPaths="true" /></system.webServer> in that app's own web.config). tests/web.config does not set this itself; on IIS Express it comes from the server-wide <asp> element in applicationhost.config instead (see Option A).tests/ app root or directly to run-all.asp.tests/web.config, run cscript //nologo tests\sync-webconfigs.vbs to refresh the nested copies used by the unit, component, and integration pages.ProductionAppBaseUrl in tests/web.config to wherever the production app actually resolves (e.g. http://localhost/ for a root site, or http://localhost/MyClassicApp/ for a virtual-directory app) and re-run the sync script so rendered-output tests know where to send HTTP requests.Example layout:
http://localhost/http://localhost/tests-dev/tests/run-all.asp includes the aspunit library and the manifest.tests/run-all.asp also applies PlainRunnerTheme.asp, a local runner theme that avoids the upstream CDN dependency in aspunit’s default UI.tests/test-manifest.asp explicitly registers each test page.tests/bootstrap.asp provides the shared runtime setup:
tests/support/HttpCaptureHelpers.asp provides safe HTTP-based page capture for rendered output assertions against the production app.The integration test page includes core/mvc.asp directly because that is the only first-wave test that needs dispatcher behavior.
Because GetAppSetting() uses Server.MapPath("web.config"), nested test folders also need a mirrored web.config alongside the executing test pages that rely on config-aware runtime files. Use tests/sync-webconfigs.vbs after changing tests/web.config.
The manifest is manual by design. There is no filesystem auto-discovery.
Open the browser runner:
Browse to run-all.asp within the tests/ IIS application, for example:
http://localhost/tests-dev/run-all.asp
aspunit renders a UI in runner mode and loads each registered page with ?task=test behind the scenes.
On Windows you can also use:
tests\run-tests.cmd
Or with an explicit runner URL:
tests\run-tests.cmd http://localhost:8085/run-all.asp
tests/unit/ for deterministic helper or registry teststests/component/ for direct controller/object tests with controlled setuptests/integration/ for narrow runtime smoke coverage, config behavior, or rendered-page capture
.asp file that:
../aspunit/Lib/ASPUnit.asp../bootstrap.aspASPUnit.AddModule(...)ASPUnit.Run()tests/test-manifest.asp.run-all.asp.public/.tests/web.config.run-all.asp loads in the separate tests/ IIS app.public/ still exposes no test runner pages or test routes.public/web.config; the test app uses a minimal mirrored config in tests/web.config.Powered by TurnKey Linux.