Consolidated ASP Classic MVC framework from best components
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

10KB

Testing MVC-Starter

This project now supports a dev-only Classic ASP test harness built with aspunit.

Scope

  • Production app: public/
  • Dev-only test app: tests/
  • Test framework: tests/aspunit/

The tests/ IIS application assumes the repository layout keeps tests/, public/, core/, and app/ as sibling directories.

File Inventory

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

IIS Setup

Option A: IIS Express via the checked-in 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.

  1. Run 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).
  2. Browse to http://localhost:8081/ (or run tests\run-tests.cmd, which syncs configs first, then opens the runner URL).
  3. 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.

Option B: A real IIS server

  1. Keep the existing production IIS app rooted at public/.
  2. Create a separate development-only IIS application rooted at tests/.
  3. Enable Classic ASP for that IIS app.
  4. Ensure parent paths are allowed for the 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).
  5. Browse to the tests/ app root or directly to run-all.asp.
  6. If you change tests/web.config, run cscript //nologo tests\sync-webconfigs.vbs to refresh the nested copies used by the unit, component, and integration pages.
  7. Set 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:

  • Production: http://localhost/
  • Tests: http://localhost/tests-dev/

How It Works

  • 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:
    • helper/config access
    • controller registry access
    • router reset
  • 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.

Running Tests

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

Adding a New Test Page

  1. Choose the right folder:
    • tests/unit/ for deterministic helper or registry tests
    • tests/component/ for direct controller/object tests with controlled setup
  • tests/integration/ for narrow runtime smoke coverage, config behavior, or rendered-page capture
    • shared layout assertions belong here too, because they verify rendered production responses rather than isolated helper behavior
  1. Create a new .asp file that:
    • includes ../aspunit/Lib/ASPUnit.asp
    • includes ../bootstrap.asp
    • registers one or more modules with ASPUnit.AddModule(...)
    • calls ASPUnit.Run()
  2. Add the page path to tests/test-manifest.asp.
  3. Reload run-all.asp.

First-Pass Isolation Policy

  • Unit tests should avoid mutating globals.
  • Registry tests should inspect current behavior, not expand the production whitelist.
  • Component tests should reset touched singleton/controller state in setup/teardown.
  • Dispatch smoke tests should initialize fresh route state before each run.

What Not To Unit Test

  • Full rendered page markup for shared-layout pages unless you add reliable output-capture support.
  • Production IIS rewrite behavior from public/.
  • Broad end-to-end request flows through the production site root.
  • Config-dependent behavior that requires machine-specific production values unless you first mirror safe test values into tests/web.config.
  • Internet access as a requirement for the runner UI. The local theme removes the upstream CDN dependency for first-wave execution.

Validation Checklist

  • run-all.asp loads in the separate tests/ IIS app.
  • All manifest pages appear in the runner.
  • Helper, registry, component, and integration suites all execute.
  • Route-helper/config integration assertions execute from the same isolated IIS app.
  • Rendered-page capture assertions can verify production HTML and status codes without polluting aspunit JSON responses.
  • Shared layout assertions can verify navbar, asset links, titles, and footer script presence across production-rendered pages.
  • Re-running the suite produces stable results.
  • The production site under public/ still exposes no test runner pages or test routes.

Limitations

  • This harness runs only inside IIS/Classic ASP; it is not intended for Linux execution.
  • The repo’s production runtime is still configured via public/web.config; the test app uses a minimal mirrored config in tests/web.config.
  • If the narrow bootstrap is not sufficient for future smoke tests, broaden only the test bootstrap first before considering production runtime changes.

Powered by TurnKey Linux.