Help us understand the problem. What is going on with this article?

Javaみたいなディレクトリ構成のPythonプロジェクトをNoseで一括テストする

More than 1 year has passed since last update.

背景

ある日、PythonのプロジェクトをJenkinsで自動テストしたいという話がありました。

それだけなら別に難しいことはありませんが、問題はそのプロジェクトのディレクトリ構成。

ディレクトリ構成(イメージ)
project
├── src
|   ├── common
|   |   └── util.py
|   ├── service1
|   |   └── module1.py
|   └── service2
|       └── module2.py
└── test
    ├── common
    |   └── test_util.py
    ├── service1
    |   └── test_module1.py
    └── service2
        └── test_module2.py

なんかJavaみたいな感じになってるぞ。Pythonの標準から外れているので工夫が必要そうですが、ひとまずやってみましょうか。

Noseの普通の使い方

Pythonでは、以下のような構成がスタンダードのようです。

Pythonの標準的なプロジェクト(パッケージ)構成
project
├── package
|   └── {ソースコード}
└── tests
    └── {テストケース}

import packageでこのパッケージのモジュールを使用するイメージですね。

一方、nosetestsのデフォルトの仕様は以下のようです。

  • ワーキングディレクトリはコマンドを実行した場所となる(そこからimportするモジュールを探す)
  • 「名前にtestが付いたディレクトリ」を再帰的に探索し、そこにある「名前にtestを含むPythonモジュール」をテストケースと見なして実行する

よって上記の標準的な構成の場合は、project直下でnosetestsと打つだけで全テストケースを実行してくれます。簡単!

Java風プロジェクトでnosetestsしてみる

まず、結論は以下のようになりました。

コマンドプロンプト
set PYTHONPATH=src;src\service1;src\service2
nosetests --tests=test\common,test\service1,test\service2

PYTHONPATH環境変数にパスを指定しておくと、nosetests実行時にそこからもモジュールを探索してくれます。また、--testsオプションでテストケースの場所を複数指定できます。

ディレクトリ構成.png

PYTHONPATHで指定しているのは図で四角で囲ったディレクトリです。これは、

  • module1.pymodule2.pyは、テストケース内で直接import module1.pyとしていた
  • util.pyは、module1.pyなどでfrom common import utilとしていた

ためです。

module1.py
from common import util

def function1():
    print('module1.function1() is called.')
    util.hello()
test_module1.py
import unittest
import module1

class TestModule1(unittest.TestCase):

    def test_function1(self):
        module1.function1()

またテストケースは、testディレクトリにさらにcommonservice1などのディレクトリを作成してその中に作成していたので、nosetestsの自動探索の範囲から外れていました。そのため、--testsで個別に指定してあげる必要があります。

こう書くと簡単そうですが、元々Pythonにあまり詳しくなかったこともあって、調査にかなり時間がかかりました。やはり標準に沿うのが一番ですね。

ttkiida
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした