web-dev-qa-db-ja.com

App_Codeに格納されているASP.netWebサイトプロジェクトコードの単体テスト

ASP.net Webサイトプロジェクト(.net 3.5)があります。現在、コードビハインド以外のすべてのコードファイル(Linq2Sqlのもの、データコンテキスト、ビジネスロジック、拡張メソッドなどを含む)はApp_Codeフォルダーにあります。

今後、プロジェクトの少なくともいくつかのセクションでユニットテスト(nunitを使用)を導入することに興味があります。私が行うユニットテストでは、現在App_Codeフォルダーにあるすべてのコードに完全にアクセスできる必要があります。私はこれまでにいくつかの最初の読書をしました、そしてコンセンサスは次のようです:

  • 私の現在の設定ではこれは不可能です
  • 単体テストでは、コンパイルされたdllの一部であるクラスを参照する必要があり、Webサイトプロジェクトは、定義上、実行時にのみコンパイルされます。
  • 続行するには、プロジェクト全体をWebアプリケーションに変換するか、テストするすべてのコード(つまり、App_Codeのコンテンツ全体)をクラスライブラリプロジェクトに移動して、クラスライブラリを参照する必要があります。 Webサイトプロジェクトのプロジェクト。これらのいずれかにより、コンパイルされたdll形式で必要なクラスへのアクセスが提供され、ユニットテストが可能になります。

これは正しいです?または、プロジェクト全体を再構築/リファクタリングせずに単体テストを実行できる別の方法はありますか?

47
Yaakov Ellis

あなたの結論は正しいようです。機能を1つまたは複数のクラスライブラリプロジェクトに移動することに投票します。これにより、他のプロジェクトでも同じ機能を再利用できるようになる可能性があります。

19
Fredrik Mörk

私のショップは、MVCプロジェクトでこれに対する答えを最終的に試しました。そして、StackOverflowで多くの行き止まりを追いかけたので、多くの人がそれができなかったと言うのを聞いて、それを共有したいと思います。私たちはこのようにします:

  • 「ローカルIISからのWebサイトとして」MVCフォルダーを開きます。これにより、インテリセンスとデバッグが正しく機能します。
  • ソース管理ディレクトリにある単体テストプロジェクトを追加します
  • Webサイトとして開いているプロジェクトにビルド前のステップを追加することはできないため、テストプロジェクトにビルド前のステップを追加します。 Webサイトが\ FooSiteで、テストプロジェクトが\ FooSite.Testsであると想像してください。コンパイルされたアプリコードは、FooSite.Tests\FooSite_Precompiled\binになります。
  • *
<Target Name="BeforeBuild">
     <AspNetCompiler VirtualPath="FooSite" TargetPath="$(ProjectDir)\FooSite_Precompiled" Force="true"
 Debug="true" />   </Target>
  • テストプロジェクトにFooSite_Precompiled/bin /App_Code.dllへの参照を追加します。
  • ブームそれだけです。あなたはあなたのケーキを持ってそれを食べることもできます。ソリューションで[ビルド]をクリックするたびに、Webサイトcsproj(まだ存在します)でaspnet_compiler.extツールを呼び出します。これはMSBuildとは異なり、app_codeをコンパイルでき、Debug = "true"を使用するとapp_codeにステップインできます。ユニットテストをデバッグするときのdllコード。また、更新された単体テストを実行している場合にのみビルドする必要があります。ページに対する変更の影響を確認する場合、app_codeフォルダーはWebサーバーから呼び出されたときに動的にコンパイルされるため、コードの変更/ページの保存/更新を行うだけです。
23
Brian White

私の会社でこの問題が発生しています(上司はDLLが好きではなく、バージョン管理についてはごみがあります...)

頻繁に使用する方法は2つあります。

1)CIツールを入手して単体テストを実行します。かなり緊密なNUnit統合を備えたTeamCityを使用しており、ソリューションはこれが有効なオプションとなるのに十分な速さで構築されます(そして十分なテストがほとんどありません)。

2)結果のバイナリを手動でプリコンパイルして単体テストする:コマンドラインからASP.netコンパイラ/ MSBuildを実行して(「公開」ビルドを実行しているかのように)、結果のバイナリを単体テストするだけで十分です。

ただし、コードをバイナリ(クラスライブラリ)に分離するか、単にWebアプリケーションを使用するオプションがある場合は、より良い代替手段としてそれをお勧めします。

11
Ed James

誰かがブライアンのソリューションを実装していることに気付いた場合は、ユニットテストソリューションに含めることができるWebsite.targetsファイルを次に示します。 App_Codeが変更された場合にのみ、Webサイトを(再)コンパイルします。次のようなものを追加するだけです

  <PropertyGroup>
    <WebsiteName>MyWebsite</WebsiteName>
    <WebsitePath>..</WebsitePath>
  </PropertyGroup>
  <Import Project="$(ProjectDir)\Website.targets" />
  <Target Name="BeforeBuild" DependsOnTargets="CompileWebsite">
  </Target>

.csprojに移動し、WebsiteNameWebsitePathをカスタマイズすると、準備が整います。 Website.targets:

<?xml version="1.0" encoding="utf-8"?>
<!--
    Target that compiles Website's App_Code to be used for testing
  -->
<Project DefaultTargets="CompileWebsite" ToolsVersion="4.0" xmlns="http://schemas.Microsoft.com/developer/msbuild/2003">
  <ItemGroup>
    <AppCodeFiles Include="$(WebsitePath)\$(WebsiteName)\App_Code\**\*.*" />
  </ItemGroup>
  <Target Name="CompileWebsite" Inputs="@(AppCodeFiles)" Outputs="$(ProjectDir)\PrecompiledWeb\bin\App_Code.dll">
    <AspNetCompiler VirtualPath="$(WebsiteName)" PhysicalPath="$(WebsitePath)\$(WebsiteName)" TargetPath="$(ProjectDir)\PrecompiledWeb" Force="true" Debug="true" />
  </Target>
  <Target Name="CleanWebsite">
    <RemoveDir Directories="$(WebsitePath)\$(WebsiteName)\PrecompiledWeb" />
  </Target>  
</Project>
6
blazee

App_code を使用している間はこれが可能であるように見えますが、FredrikとColinが示唆しているように、このロジックを独自のクラスライブラリプロジェクトに移動するか、プロジェクトタイプをWebアプリケーションに変更します。

私は常に独自のASP.NETプロジェクトをWebサイトではなくWebアプリケーションプロジェクトとして作成しています。

2
RichardOD

また、OPが述べたように、Webアプリプロジェクトに移動することも可能です。これは、よりクリーンであると言えます。ページはwepアプリプロジェクトにとどまることができ、1 DLL =(テスト可能)。すべてのビジネスロジックなどは、個別のクラスライブラリに格納されます。

1
Colin

プロジェクトをWebアプリに変換したり、クラスをクラスライブラリプロジェクトに移動したりせずに、App_Codeフォルダーに格納されているクラスを単体テストすることができます。

必要なのは、コードファイルのビルドアクションをコンパイルに設定することだけです。これにより、Webサイトのデバッグと単体テストで.dllファイルが出力されます。

これで、単体テストプロジェクトからWebサイトプロジェクトを参照すると、app_codeフォルダー内のクラスが表示されます。

注意:

.csファイルの設定 'Build ActionからCompileを指定すると、Webサイトはデバッグと単体テストで.dllファイルを生成します。 IISはbinとApp_Codeフォルダーの2つの場所でコードを検出し、どちらを使用するかわからないため、.dllファイルはWebサイトのデバッグ時に問題を引き起こします。デバッグしたいときに.dllファイルを削除します。

0
Jared Beach

PhysicalPath属性を追加して、BrianWhiteのソリューションを変更する必要がありました。さらに、私はDefault Web Siteを使用しておらず、VirtualPathプロパティを自分のWebサイト名に変更する必要がありました。

<Target Name="BeforeBuild">
    <AspNetCompiler VirtualPath="myIISsitename.com" PhysicalPath="$(SolutionDir)MySiteFolder" TargetPath="$(ProjectDir)\MySite_Precompiled" Force="true" Debug="true" />
</Target>

結果のdllはMySite_Precompiled\App_Code.dllになります

0
Jason