<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Mysetup パターン: アプリケーションに特化したテストフィクスチャ</title> <link rel="stylesheet" href="../_static/sphinxdoc.css" type="text/css" /> <link rel="stylesheet" href="../_static/pygments.css" type="text/css" /> <script type="text/javascript"> var DOCUMENTATION_OPTIONS = { URL_ROOT: '../', VERSION: '2.2.4.0', COLLAPSE_INDEX: false, FILE_SUFFIX: '.html', HAS_SOURCE: true }; </script> <script type="text/javascript" src="../_static/jquery.js"></script> <script type="text/javascript" src="../_static/underscore.js"></script> <script type="text/javascript" src="../_static/doctools.js"></script> <script type="text/javascript" src="../_static/translations.js"></script> <link rel="top" title="None" href="../index.html" /> <link rel="up" title="使用方法と例" href="index.html" /> <link rel="next" title="パラメーターテスト" href="parametrize.html" /> <link rel="prev" title="基本的なパターンと例" href="simple.html" /> </head> <body> <div class="related"> <h3>ナビゲーション</h3> <ul> <li class="right" style="margin-right: 10px"> <a href="../py-modindex.html" title="Pythonモジュール索引" >モジュール</a></li> <li class="right" > <a href="parametrize.html" title="パラメーターテスト" accesskey="N">次へ</a> |</li> <li class="right" > <a href="simple.html" title="基本的なパターンと例" accesskey="P">前へ</a> |</li> <li><a href="../contents.html">pytest-2.2.4.0</a> »</li> <li><a href="index.html" accesskey="U">使用方法と例</a> »</li> </ul> </div> <div class="sphinxsidebar"> <div class="sphinxsidebarwrapper"> <h3><a href="../contents.html">目次</a></h3> <ul> <li><a class="reference internal" href="#">Mysetup パターン: アプリケーションに特化したテストフィクスチャ</a><ul> <li><a class="reference internal" href="#id2">ステップ 1: アプリケーションに特化した <tt class="docutils literal"><span class="pre">mysetup</span></tt> パターンの実装</a></li> <li><a class="reference internal" href="#tut-cmdlineoption">ステップ 2: コマンドラインオプションとテストのスキップを確認</a></li> </ul> </li> </ul> <h4>前のトピックへ</h4> <p class="topless"><a href="simple.html" title="前の章へ">基本的なパターンと例</a></p> <h4>次のトピックへ</h4> <p class="topless"><a href="parametrize.html" title="次の章へ">パラメーターテスト</a></p> <div id="searchbox" style="display: none"> <h3>クイック検索</h3> <form class="search" action="../search.html" method="get"> <input type="text" name="q" /> <input type="submit" value="検索" /> <input type="hidden" name="check_keywords" value="yes" /> <input type="hidden" name="area" value="default" /> </form> <p class="searchtip" style="font-size: 90%"> モジュール、クラス、または関数名を入力してください </p> </div> <script type="text/javascript">$('#searchbox').show(0);</script> </div> </div> <div class="document"> <div class="documentwrapper"> <div class="bodywrapper"> <div class="body"> <div class="section" id="mysetup"> <span id="id1"></span><h1>Mysetup パターン: アプリケーションに特化したテストフィクスチャ<a class="headerlink" href="#mysetup" title="このヘッドラインへのパーマリンク">¶</a></h1> <p>アプリケーションに特化したテストのセットアップを管理したり、相互にやり取りする、基本的且つ便利なサンプルを順を追って紹介します。その目的としては、アプリケーションオブジェクトの一連の開始処理や設定のグルーコードやテストコードを1つの場所に集め、実行時にテストモジュールとテスト関数からそういった処理の詳細を見えなくすることです。</p> <div class="section" id="id2"> <h2>ステップ 1: アプリケーションに特化した <tt class="docutils literal"><span class="pre">mysetup</span></tt> パターンの実装<a class="headerlink" href="#id2" title="このヘッドラインへのパーマリンク">¶</a></h2> <p><tt class="docutils literal"><span class="pre">mysetup</span></tt> という関数の引数を使って、簡単なテスト関数を書いてみましょう:</p> <div class="highlight-python"><div class="highlight"><pre><span class="c"># test_sample.py の内容</span> <span class="k">def</span> <span class="nf">test_answer</span><span class="p">(</span><span class="n">mysetup</span><span class="p">):</span> <span class="n">app</span> <span class="o">=</span> <span class="n">mysetup</span><span class="o">.</span><span class="n">myapp</span><span class="p">()</span> <span class="n">answer</span> <span class="o">=</span> <span class="n">app</span><span class="o">.</span><span class="n">question</span><span class="p">()</span> <span class="k">assert</span> <span class="n">answer</span> <span class="o">==</span> <span class="mi">42</span> </pre></div> </div> <p>このテストを実行するために py.test は、関数の引数に与えられた <tt class="docutils literal"><span class="pre">mysetup</span></tt> を扱うファクトリー関数を探して呼び出す必要があります。このファクトリー関数を探し出せるように <a class="reference internal" href="../plugins.html#localplugin"><em>local プラグイン</em></a> に特別な名前をもつファクトリーメソッドを書きます:</p> <div class="highlight-python"><div class="highlight"><pre><span class="c"># conftest.py の内容</span> <span class="kn">from</span> <span class="nn">myapp</span> <span class="kn">import</span> <span class="n">MyApp</span> <span class="k">def</span> <span class="nf">pytest_funcarg__mysetup</span><span class="p">(</span><span class="n">request</span><span class="p">):</span> <span class="c"># "mysetup" ファクトリー関数</span> <span class="k">return</span> <span class="n">MySetup</span><span class="p">()</span> <span class="k">class</span> <span class="nc">MySetup</span><span class="p">:</span> <span class="c"># このインスタンスはテスト関数から見える</span> <span class="k">def</span> <span class="nf">myapp</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="k">return</span> <span class="n">MyApp</span><span class="p">()</span> </pre></div> </div> <p>このサンプルを実行するために <tt class="docutils literal"><span class="pre">MyApp</span></tt> アプリケーションオブジェクトの簡単なスタブを作ります:</p> <div class="highlight-python"><div class="highlight"><pre><span class="c"># myapp.py の内容</span> <span class="k">class</span> <span class="nc">MyApp</span><span class="p">:</span> <span class="k">def</span> <span class="nf">question</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="k">return</span> <span class="mi">6</span> <span class="o">*</span> <span class="mi">9</span> </pre></div> </div> <p>テストを実行します:</p> <div class="highlight-python"><pre>$ py.test test_sample.py =========================== test session starts ============================ platform linux2 -- Python 2.7.1 -- pytest-2.2.4 collecting ... collected 1 items test_sample.py F ================================= FAILURES ================================= _______________________________ test_answer ________________________________ mysetup = <conftest.MySetup instance at 0x17f21b8> def test_answer(mysetup): app = mysetup.myapp() answer = app.question() > assert answer == 42 E assert 54 == 42 test_sample.py:4: AssertionError ========================= 1 failed in 0.01 seconds =========================</pre> </div> <p><tt class="docutils literal"><span class="pre">mysetup</span></tt> オブジェクトが正常にインスタンス化されて、 <tt class="docutils literal"><span class="pre">mysetup.app()</span></tt> が初期化された <tt class="docutils literal"><span class="pre">MyApp</span></tt> インスタンスを返しました。あなたが具体的に何を聞けば良いのか、もしくは実際に何が起こったかに混乱しているなら、その質問に関して尋ねられます。 <a class="reference external" href="http://uncyclopedia.wikia.com/wiki/The_Hitchhiker's_Guide_to_the_Galaxy">ここ</a> をご覧ください。</p> </div> <div class="section" id="tut-cmdlineoption"> <span id="id4"></span><h2>ステップ 2: コマンドラインオプションとテストのスキップを確認<a class="headerlink" href="#tut-cmdlineoption" title="このヘッドラインへのパーマリンク">¶</a></h2> <p>コマンドラインオプションを追加するには、前述したサンプルの <tt class="docutils literal"><span class="pre">conftest.py</span></tt> に、コマンドラインオプションを追加して新たな mysetup メソッドを提供するように変更します:</p> <div class="highlight-python"><div class="highlight"><pre><span class="c"># ./conftest.py の内容</span> <span class="kn">import</span> <span class="nn">pytest</span> <span class="kn">from</span> <span class="nn">myapp</span> <span class="kn">import</span> <span class="n">MyApp</span> <span class="k">def</span> <span class="nf">pytest_funcarg__mysetup</span><span class="p">(</span><span class="n">request</span><span class="p">):</span> <span class="c"># "mysetup" ファクトリー関数</span> <span class="k">return</span> <span class="n">MySetup</span><span class="p">(</span><span class="n">request</span><span class="p">)</span> <span class="k">def</span> <span class="nf">pytest_addoption</span><span class="p">(</span><span class="n">parser</span><span class="p">):</span> <span class="n">parser</span><span class="o">.</span><span class="n">addoption</span><span class="p">(</span><span class="s">"--ssh"</span><span class="p">,</span> <span class="n">action</span><span class="o">=</span><span class="s">"store"</span><span class="p">,</span> <span class="n">default</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">help</span><span class="o">=</span><span class="s">"specify ssh host to run tests with"</span><span class="p">)</span> <span class="k">class</span> <span class="nc">MySetup</span><span class="p">:</span> <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">request</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">config</span> <span class="o">=</span> <span class="n">request</span><span class="o">.</span><span class="n">config</span> <span class="k">def</span> <span class="nf">myapp</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="k">return</span> <span class="n">MyApp</span><span class="p">()</span> <span class="k">def</span> <span class="nf">getsshconnection</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="n">host</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">config</span><span class="o">.</span><span class="n">option</span><span class="o">.</span><span class="n">ssh</span> <span class="k">if</span> <span class="n">host</span> <span class="ow">is</span> <span class="bp">None</span><span class="p">:</span> <span class="n">pytest</span><span class="o">.</span><span class="n">skip</span><span class="p">(</span><span class="s">"specify ssh host with --ssh"</span><span class="p">)</span> <span class="k">return</span> <span class="n">execnet</span><span class="o">.</span><span class="n">SshGateway</span><span class="p">(</span><span class="n">host</span><span class="p">)</span> </pre></div> </div> <p>次のようにテスト関数から <tt class="docutils literal"><span class="pre">mysetup.getsshconnection()</span></tt> メソッドを使えます:</p> <div class="highlight-python"><div class="highlight"><pre><span class="c"># test_ssh.py の内容</span> <span class="k">class</span> <span class="nc">TestClass</span><span class="p">:</span> <span class="k">def</span> <span class="nf">test_function</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">mysetup</span><span class="p">):</span> <span class="n">conn</span> <span class="o">=</span> <span class="n">mysetup</span><span class="o">.</span><span class="n">getsshconnection</span><span class="p">()</span> <span class="c"># conn を使ってテストする</span> </pre></div> </div> <p>実行すると次のようなレポートが表示されます:</p> <div class="highlight-python"><pre>$ py.test test_ssh.py -rs =========================== test session starts ============================ platform linux2 -- Python 2.7.1 -- pytest-2.2.4 collecting ... collected 1 items test_ssh.py s ========================= short test summary info ========================== SKIP [1] /tmp/doc-exec-220/conftest.py:22: specify ssh host with --ssh ======================== 1 skipped in 0.01 seconds =========================</pre> </div> <p><tt class="docutils literal"><span class="pre">py.test</span> <span class="pre">--ssh=python.org</span></tt> のようにコマンドラインオプションを指定すると、期待した通りにテストが実行されます。</p> <p><tt class="docutils literal"><span class="pre">TestClass</span></tt> も <tt class="docutils literal"><span class="pre">test_function</span></tt> のどちらとも、テストの状態をセットアップする方法について何も知る必要がないことに注目してください。 <tt class="docutils literal"><span class="pre">conftest.py</span></tt> ファイルの “テストをセットアップするグルー” コードは別々に処理されます。テストコード内で必要に応じて <tt class="docutils literal"><span class="pre">mysetup</span></tt> オブジェクトを拡張するのは簡単です。 <tt class="docutils literal"><span class="pre">conftest.py</span></tt> ファイルの配下にあるファイルやディレクトリの、任意のテスト関数によって使われます。</p> </div> </div> </div> </div> </div> <div class="clearer"></div> </div> <div class="related"> <h3>ナビゲーション</h3> <ul> <li class="right" style="margin-right: 10px"> <a href="../py-modindex.html" title="Pythonモジュール索引" >モジュール</a></li> <li class="right" > <a href="parametrize.html" title="パラメーターテスト" >次へ</a> |</li> <li class="right" > <a href="simple.html" title="基本的なパターンと例" >前へ</a> |</li> <li><a href="../contents.html">pytest-2.2.4.0</a> »</li> <li><a href="index.html" >使用方法と例</a> »</li> </ul> </div> <div class="footer"> © Copyright 2011, holger krekel et alii. このドキュメントは <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3 で生成しました。 </div> </body> </html>