ASP.net Webサイトプロジェクト(.net 3.5)があります。現在、コードビハインド以外のすべてのコードファイル(Linq2Sqlのもの、データコンテキスト、ビジネスロジック、拡張メソッドなどを含む)はApp_Codeフォルダーにあります。
今後、プロジェクトの少なくともいくつかのセクションでユニットテスト(nunitを使用)を導入することに興味があります。私が行うユニットテストでは、現在App_Codeフォルダーにあるすべてのコードに完全にアクセスできる必要があります。私はこれまでにいくつかの最初の読書をしました、そしてコンセンサスは次のようです:
これは正しいです?または、プロジェクト全体を再構築/リファクタリングせずに単体テストを実行できる別の方法はありますか?
あなたの結論は正しいようです。機能を1つまたは複数のクラスライブラリプロジェクトに移動することに投票します。これにより、他のプロジェクトでも同じ機能を再利用できるようになる可能性があります。
私のショップは、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サーバーから呼び出されたときに動的にコンパイルされるため、コードの変更/ページの保存/更新を行うだけです。
私の会社でこの問題が発生しています(上司はDLLが好きではなく、バージョン管理についてはごみがあります...)
頻繁に使用する方法は2つあります。
1)CIツールを入手して単体テストを実行します。かなり緊密なNUnit統合を備えたTeamCityを使用しており、ソリューションはこれが有効なオプションとなるのに十分な速さで構築されます(そして十分なテストがほとんどありません)。
2)結果のバイナリを手動でプリコンパイルして単体テストする:コマンドラインからASP.netコンパイラ/ MSBuildを実行して(「公開」ビルドを実行しているかのように)、結果のバイナリを単体テストするだけで十分です。
ただし、コードをバイナリ(クラスライブラリ)に分離するか、単にWebアプリケーションを使用するオプションがある場合は、より良い代替手段としてそれをお勧めします。
誰かがブライアンのソリューションを実装していることに気付いた場合は、ユニットテストソリューションに含めることができるWebsite.targetsファイルを次に示します。 App_Codeが変更された場合にのみ、Webサイトを(再)コンパイルします。次のようなものを追加するだけです
<PropertyGroup>
<WebsiteName>MyWebsite</WebsiteName>
<WebsitePath>..</WebsitePath>
</PropertyGroup>
<Import Project="$(ProjectDir)\Website.targets" />
<Target Name="BeforeBuild" DependsOnTargets="CompileWebsite">
</Target>
.csprojに移動し、WebsiteName
とWebsitePath
をカスタマイズすると、準備が整います。 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>
App_code を使用している間はこれが可能であるように見えますが、FredrikとColinが示唆しているように、このロジックを独自のクラスライブラリプロジェクトに移動するか、プロジェクトタイプをWebアプリケーションに変更します。
私は常に独自のASP.NETプロジェクトをWebサイトではなくWebアプリケーションプロジェクトとして作成しています。
また、OPが述べたように、Webアプリプロジェクトに移動することも可能です。これは、よりクリーンであると言えます。ページはwepアプリプロジェクトにとどまることができ、1 DLL =(テスト可能)。すべてのビジネスロジックなどは、個別のクラスライブラリに格納されます。
プロジェクトをWebアプリに変換したり、クラスをクラスライブラリプロジェクトに移動したりせずに、App_Codeフォルダーに格納されているクラスを単体テストすることができます。
必要なのは、コードファイルのビルドアクションをコンパイルに設定することだけです。これにより、Webサイトのデバッグと単体テストで.dllファイルが出力されます。
これで、単体テストプロジェクトからWebサイトプロジェクトを参照すると、app_codeフォルダー内のクラスが表示されます。
注意:
.csファイルの設定 'Build Action
からCompile
を指定すると、Webサイトはデバッグと単体テストで.dllファイルを生成します。 IISはbinとApp_Codeフォルダーの2つの場所でコードを検出し、どちらを使用するかわからないため、.dllファイルはWebサイトのデバッグ時に問題を引き起こします。デバッグしたいときに.dllファイルを削除します。
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
になります