MyEnigma

とあるエンジニアのブログです。#Robotics #Programing #C++ #Python #MATLAB #Vim #Mathematics #Book #Movie #Traveling #Mac #iPhone

PythonのデフォルトのUnitTestsではなくpytestを使うべき7つの理由

目次

  • 目次
  • はじめに
  • PythonのデフォルトのUnitTestsではなくpytestを使うべき7つの理由
    • 1. クラスを作らずにシンプルな関数でテスト関数を作ることができる。
    • 2. 様々なassert関数を覚えなくて良い
    • 3. テストが失敗した理由がわかりやすい
    • 4. テストの検索と実行が高機能 (auto discovery)
    • 5. 様々なプラグインが公開されており、簡単に機能追加できる
    • 6. UnitTestsで作成されたテストも実行できる
    • 7. テストの実行時間のランキングを簡単に作成してくれる
  • 便利なコマンドライン引数表
  • PythonのIDEとpytestの連携
  • 参考資料
  • MyEnigma Supporters

はじめに

これまで、自分はPythonのユニットテストには、

PythonのデフォルトのUnitTestsを使っていましたが、

docs.python.org

myenigma.hatenablog.com

自分がコントリビュートしているPython OSSの殆どが

pytestというテストフレームを使っていたので、

気になって調べてみました。

docs.pytest.org

PythonのデフォルトのUnitTestsではなくpytestを使うべき7つの理由

下記は、これまでPythonデフォルトのUnitTestsを使ってきた自分が、

pytestを使ったほうが良いなと思った7つの項目です。

 

1. クラスを作らずにシンプルな関数でテスト関数を作ることができる。

UnitTestsはJavaのユニットテストフレームワークである

JUnitをベースとして開発されているため、

docs.python.org

テストを作成する時に毎回UnitTestsクラスを継承した

テストクラスを作成する必要があります。

 

一方、pytestの場合、クラスは作る必要がなく、

test_*.py または、*_test.pyというファイルに、

test_*という名前の関数をさえ作れば、

pytestが勝手にその関数を検索して、テストとして実行してくれます。

 

これにより、テストを書く敷居がかなり低くなり、

テストを書きやすくなると思います。

 

2. 様々なassert関数を覚えなくて良い

UnitTestのテストは、assertTrueやassertEqualなど、

様々なassert関数を使ってテストを作成しますが、

どのようなassert関数使うべきか覚える必要があります。

 

pytestでは、Pythonのデフォルトキーワードである

assert文を使って、条件を書くことによりテストを評価します。

これにより、すべてのテストコードを一貫性をもって、

作成することができると思います。

 

3. テストが失敗した理由がわかりやすい

UnitTestsで作成したテストが失敗した場合、

そのテストが失敗したことはわかりますが、

なぜそのテストが失敗したのかは、

テストの結果をみるだけではわかりにくいと思っていました。

 

一方、pytestの場合、

下記の公式ドキュメントにあるように

失敗したテストに関しては、

それぞれの値がどのような値であったせいで、

テストが失敗したのかをわかりやすく表示してくれます。

docs.pytest.org

 

加えて、コマンドライン引数で設定することにより、

テストが失敗したときに定義されていた

それぞれの変数の中身なども表示することができ、

再度テストを実行しなくても、

テストのログだけで、ある程度のデバックができるようになっています。

 

4. テストの検索と実行が高機能 (auto discovery)

UnitTestsにも、自動的にテストコードを検索して、実行する

auto discovery機能がありますが、

pytestにauto discoveryはより一層使いやすく、高機能だと思います。

 

例えば、

$ pytest

とタイプすることで自動的にcurrent directory以下のテストを検索してくれますが、

検索するディレクトリを指定したり、

あるテストファイルの一部のテストのみ実行したり、

テスト名の部分一致で検索して実行なども

すべてコマンドライン引数を設定することで可能です。

 

5. 様々なプラグインが公開されており、簡単に機能追加できる

pytestには、プラグイン機能があり、

様々な便利な追加機能のためのプラグインが公開されています。

 

例えば、

マルチスレッドや分散処理でテストを並列実行するpytest-xdistや

pypi.org

文法/コードスタイルチェッカーであるpyflakesを実行するpytest-flakes

github.com

コードカバレッジを確認するpytest-cov

pypi.org

などがあります。

これらのプラグインは、それぞれpipでインストールでき、

あとは必要な設定やデータをpytestのオプションに指定すれば

それぞれの機能を利用可能です。

 

6. UnitTestsで作成されたテストも実行できる

pytestは、Pythonのデフォルトのテストフレームワークである

unittestで作成されたテストも実行可能です。

docs.python.org

これにより、すでに沢山のUnitTestsベースのテストが存在している

プロジェクトにおいても、pytestで既存のテストを実行しつつ、

少しづつ、pytestのテストに置き換えていくことができます。

 

また、UnitTestsベースのテストが失敗したときも、

pytestで実行した場合、わかりやすく失敗した理由を表示してくれます。

 

7. テストの実行時間のランキングを簡単に作成してくれる

--duration=0というオプションを使うことにより、

簡単にテストの実行時間の遅いものからランキングリストを作ってくれます。

下記は自分のOSSの場合の出力例です:

f:id:meison_amsl:20210131212126p:plain

上記のように、簡単にどのテストが失敗しているのかわかり、

そのような遅いテストを改善したり、

テスト対象のコードそのものを改善することができます。

 

便利なコマンドライン引数表

コマンドライン引数 機能
-l トレースバックとともにローカル変数も表示
-v すべてのテスト名とその結果を表示
--lf 前回失敗したテストだけを実行
-x 最初の失敗したテストでテストを止める
-Werror Warningが出たときもエラーにする
--durations=N テスト実行時間がN秒以下のテストを表示(0に場合はすべて)

 

PythonのIDEとpytestの連携

JetbrainsのPython IDEであるPycharmは、

myenigma.hatenablog.com

テストフレームワークとして、pytestに対応しています。

下記の公式ドキュメントにある通り、

IDEからテストを実行し、テスト結果をわかりやすく表示したり、

auto discoveryでテストを検索することもできます。

pleiades.io

pleiades.io

 

続きを読む

SciPy 1.6.0がリリースされました

目次

  • 目次
  • はじめに
  • Tweetまとめ
  • 参考資料
  • MyEnigma Supporters

はじめに

本日、

自分が開発者のメンバーとして参加している

SciPyの新しいバージョン1.6.0がリリースされました🎉

github.com

 

今回は、1.6.0の新機能や特徴を、

連続ツイートでまとめてみたので、

そちらを、あとから参照しやすいように

記事としてまとめておきます。

 

過去のバージョンの記事は下記の通りです。

myenigma.hatenablog.com

 

続きを読む

Google製のJava便利ライブラリGuava入門

目次

  • 目次
  • はじめに
  • com.google.common.base.Optional
  • com.google.common.base.Preconditions
  • com.google.common.collect.Ordering
  • com.google.common.collect.Range
  • com.google.common.collect.Multiset
  • com.google.common.collect.Multimap
  • com.google.common.collect.Bimap
  • com.google.common.collect.Table
  • com.google.common.cache
  • com.google.common.base.Joiner
  • com.google.common.base.Splitter
  • com.google.common.primitives
  • com.google.common.base.Stopwatch
  • com.google.common.collect.ImmutableList
  • @VisibleForTesting
  • Unsigned対応
  • Graph
  • 参考資料
  • MyEnigma Supporters

はじめに

PythonやJuliaを使っている人が、

Javaを使うと、

言語のデフォルト機能が足りないなと

思うことがあると思います。

 

そんな時に便利なのが、

Googleが開発公開しているJavaライブラリであるGuavaです。

github.com

qiita.com

 

Guavaは、Javaのデフォルト機能で実装すると、

コードの量が長くなってしまったり、

バグが入りやすくなってしまうコードを、

簡潔に、バグが入りにくく実装することを

目的に開発されています。

 

Guavaはかなり古くから開発されているため、

Java8などで導入された機能とかぶっている部分も多いですが、

それでもまだデフォルトの機能にはない沢山の機能が実装されています。

 

今回の記事では、

Guavaの代表的な機能の概要と

コードサンプルを紹介したいと思います。

 

すべてのコードサンプルはこちらでも公開しています。

github.com

続きを読む

数理最適化初心者のための(線形)割当問題の概要とscipy.optimize.linear_sum_assignmentによる解法

目次

  • 目次
  • はじめに
  • (線形)割当問題とは?
  • scipyを使った解法
  • 参考資料
  • MyEnigma Supporters

はじめに

今回の記事は、

数理最適化Advent Calendar 2020の23日目の記事です。

qiita.com

 

今回の記事では、

数理最適化の基本的な問題の一つである、(線形)割当問題の概要と、

www.msi.co.jp

Pythonのライブラリの一つであるscipyを使った解法について紹介したいと思います。

www.scipy.org

続きを読む

書評メモ:『ゼロから学ぶPythonプログラミング Google Colaboratoryでらくらく導入』

目次

  • 目次
  • はじめに
  • 書評メモ
  • 参考資料
  • MyEnigma Supporters

はじめに

冒頭の書籍を読んだ書評メモです。

続きを読む

Web初心者のためのWebSocket概要と各言語におけるサンプルコード


WebSocket: Lightweight Client-Server Communications (English Edition)

目次

  • 目次
  • はじめに
  • WebSocketとは?
  • Pythonにおけるサンプルコード
  • Juliaにおけるサンプルコード
  • サンプルコードのリポジトリ
  • 参考資料
  • MyEnigma Supporters

はじめに

以前、通常のHTTPを使った、

簡単なプロセス間通信の方法を記事にしましたが、

myenigma.hatenablog.com

myenigma.hatenablog.com

 

通常のHTTPでは、

通信方式request-response型なので、

クライアントがサーバに話しかけないと、

サーバが、クライアントに話しかけることができませんでした。

そこでウェブアプリケーションにおいて、

双方通信によく使われるのがWebSocketです。

ja.wikipedia.org

今回はこのWebSocketについて概要と

各言語でのサンプルコードを紹介したいと思います。  

続きを読む

Juliaコードの初回実行を高速化するためのPackageCompiler.jl入門


1から始める Juliaプログラミング

目次

  • 目次
  • はじめに
  • パッケージのロードをsysimageで高速化する
  • 関数の初期実行をsysimagesで高速化する
  • REPL用のデフォルトパッケージをロードしたsysimageを作る便利関数
  • 参考資料
  • MyEnigma Supporters

はじめに

これまでPythonでやってきたことを、

Juliaで置き換えようとすると、まず初めにぶつかるのが、

Juliaのコードにおけるライブラリのロードや、

初めて使う関数の計算が遅いなど、

いわゆる初回実行が遅い問題が気になってきます。

(英語ではこの問題をlatencyと呼んでいるそうです

github.com

)

 

Juliaは基本的に初回実行時にコードをJITコンパイルして実行するため、

動的言語でありながら、高速な実行を実現できているので、

myenigma.hatenablog.com

この初回実行が遅いのはある程度はしょうがないのかなと思います。

 

しかし、

毎回使うライブラリのロードや

変更が不要な関数が、

毎回遅いのはなんとかならないのかなと思っていました。

 

そこで、この問題の一つの解決策がPackageCompiler.jlです。

github.com

julialang.github.io

 

概要はこちらの動画を参照していただけるとわかると思いますが、

www.youtube.com

sysimageと呼ばれるJuliaのセッション保存機能を使って、

いつも利用するライブラリをロードした状態や、

関数のJITコンパイル結果を保存することにより、

そのsysimageを使って、juliaコードを実行したときに、

初回実行を高速化することができます。

(Julianのsysimageに関しては、こちらを参照ください

julialang.github.io)

 

今回の記事では、このPackageCompiler.jlとsysimagesを使うことで、

Juliaのコードの初回実行を高速化する方法を簡単に紹介したいと思います。

続きを読む

GitHubのOSSで最新のドキュメントを各コミット毎に簡単に確認できるようにする


SphinxでKindle本を作る

目次

  • 目次
  • はじめに
  • Circle CIでドキュメントをビルドするCIを作る
  • circleci-artifacts-redirectorを設定する
  • 参考資料
  • MyEnigma Supporters

はじめに

OSSにとってドキュメントは、

出来るだけ多くの人に使ってもらうために重要です。

 

近年のOSSでは、

ソースコードと同じgitリポジトリに

テキストベースでドキュメントの元のデータを管理し、

Sphinxや

www.sphinx-doc.org

Documenter,jl

github.com

のようなドキュメント作成ライブラリを使って、

htmlベースのドキュメントを自動生成し、

そのデータをインターネット上に公開するのが一般的です。

 

このようにドキュメントをgitで管理すると、

ドキュメントの改善を通常のコードと同様に

プルリクエストベース(PR)で、レビューして

改善することができます。

 

このような、

PRベースでドキュメントの変更をレビューするのは便利なのですが、

一つ面倒なのが、

他人のドキュメントのPRをレビューするときに、

そのPRのブランチを手元にチェックアウトし、

ドキュメントをビルドしないと、

最新のドキュメントの見た目などを確認できないことです。

 

また、レビューの結果を反映した、

各コミット毎にこの作業をしないといけないので

以前から非常に面倒だなと感じていました。

 

昔からこのフローを改善したいなと思っていたのですが、

最近開発に参加している、SciPyが非常に良い方法を利用しているのに気がつきました。

github.com

 

この方法では、

PRの各コミット毎にCIが回るので、

そのCIの一環として、最新のコードでドキュメントをビルドし、

そのドキュメントをそのままブラウザ上で確認出来るようになります。

 

もう少し具体的には、

下記のように、PRでコミットすると

GitHubのCIの画面に、

build_doc artifactという項目が表示され、

f:id:meison_amsl:20200725204409p:plain

 

この項目のDetailsをクリックすると、

下記のように、CIで生成された最新のドキュメントを

ブラウザ上で確認することができます。

f:id:meison_amsl:20200725204515p:plain

これを見ながら、

簡単に最新のドキュメントの結果をレビューすることができます。

 

今回の記事では、

こちらの設定方法について説明します。

続きを読む

SciPy 1.5.0がリリースされました


LAPACK利用の手引―行列計算パッケージ

目次

  • 目次
  • はじめに
  • Tweetまとめ
  • 参考資料
  • MyEnigma Supporters

はじめに

本日、

自分が開発者のメンバーとして参加している

SciPyの新しいバージョン1.5.0がリリースされました🎉

github.com

 

今回は、1.5.0の新機能や特徴を、

連続ツイートでまとめてみたので、

そちらを、あとから参照しやすいように

記事としてまとめておきます。

続きを読む

ロボティクスにおける最近傍点探索のためのscipy.spatial.cKDTree入門


NumPy&SciPy数値計算実装ハンドブック (Pythonライブラリ定番セレクション)

目次

  • 目次
  • はじめに
  • kdtreeとは
  • scipy.spatial.cKDTreeの使い方
    • kdtreeの作成
    • 最近傍点の探索
    • ある点から一定範囲の点を探索
    • 2つのkd-tree同士のある一定距離範囲内の点の探索
    • 1つのkd-tree内のある一定距離範囲内の点の探索
    • 2つのkd-treeの各点の距離を計算する
  • 参考資料
  • MyEnigma Supporters

はじめに

ロボティクスにおいて、

最近傍点探索はよく使われる計算です。

例えば、衝突検知や、センサ情報の対応点探索などに

最近傍点探索は使われます。

 

最近傍点探索を使う時に、

一番よく問題になるのが、計算量です。

単純にbrute forceで最近傍点を探すと、

計算時間は探索する点の数に応じて増加してしまいます。

 

そこで、よく使われるのがkd-treeです。

en.wikipedia.org

このkd-treeを使うことで、大量のデータがあっても、

比較的、高速に最近傍点探索を計算することができます。

 

このkd-treeを使うには、

様々なライブラリがすでに存在しています.

例えば、以前紹介したFLANNも

kd-treeをデータ構造に利用しています。

myenigma.hatenablog.com

 

今回の記事では、

Pythonの科学技術計算のライブラリであるSciPyの中にある、

scipy.spatial.cKDTreeというモジュールの使い方を紹介したいと思います。

scipy.github.io

 

ちなみに、scipy.spatial.KDTreeというモジュールがありますが、

scipy.github.io

こちらは、純Pythonで実装されたkdtreeで、

cKDTreeがcythonで高速化されたバージョンのKDTreeです。

こちらのroadmapにある通り、将来的にはcKDTreeがKDTreeに

置き換えられる予定ですので、cKDTreeを紹介します。

scipy.github.io

 

現時点では、この移行のために、

KDTreeもcKDTreeもほぼ同じAPIをもっていますので、

現時点では、計算が高速なcKDTreeを使っておくのが良いと思います。

(また最近追加された機能はcKDTreeにしか追加されないようになっているため、

若干、cKDTreeのほうが多機能です。)

 

続きを読む