Consolidated ASP Classic MVC framework from best components
Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

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.