目次: Linux
会社ではThinkPad X1 Carbon 12th GenにUbuntu 24.04 LTSをインストールして使っています。Lenovoが公式サポートしている(Lenovoのサイトへのリンク、正確にはUbuntu 22.04を正式サポート)だけあり、大体は問題なく動作しますが、使って数日にして既に困った点が2つほど出てきました。
困った点その1はWi-Fiです。会社のWi-Fiと相性が悪いのか接続がブチブチ途切れます。全く仕事にならないので、諦めてUSB接続の有線Ethernetアダプタを使っています。有線接続バンザイ。
困った点その2は感圧式タッチパッドです。Gen 12からクリック用のボタンを廃し、タッチパッドは単なる板になりました。板を押した圧力を検知してゴツンと押し返すことでクリック感を表現するデバイスです。個人的には手が疲れるので嫌いです。
感圧式タッチパッドのドライバがおかしいのか、たまに感圧機能がバカになりクリックにめちゃくちゃ力が必要になってしまいます。この症状が発生すると設定ウインドウにタッチパッドの項目が出なくなります。もしこの症状になったときは、
$ sudo rmmod i2c_hid_acpi && sudo modprobe i2c_hid_acpi
これで直りました。この直し方見つけた人すごいですね。どうやって見つけたんだろうね……?
目次: Python
最近Pythonを触ることが増えたのでテストについて調べようと思い立ちました。超有名テストフレームワークpytestがありますので、無から使い始めるまでを試します。
環境はDebian Testingで、ツールのバージョンはpython 3.12.6, pytest 8.2.2です。
設定ファイルは新し目のpyproject.tomlにします。その他の選択肢についてはpytestのドキュメントを参照ください。設定ファイルではpytest実行時のオプション、テスト用のスクリプトが置いてあるディレクトリを指定します。
# pyproject.toml
[tool.pytest.ini_options]
minversion = "6.0"
addopts = "-ra -q"
testpaths = [
"tests",
]
サンプルにあるオプションの説明をしておくと、
となります。これらの効果を打ち消したければ、
オプションを使うと良いみたいです。
全体構造はこんな感じです。
. |-- pyproject.toml |-- sample | `-- main.py `-- tests |-- __init__.py ★★空っぽでOK★★ `-- test_main.py
テストするにはテスト対象のコードが必要です。とりあえず成功と失敗を見たいので、合っている関数と間違っている関数の2つを作りました。アホみたいなコードですけど気にしないでください。
# sample/main.py
def my_add(a, b):
print('my_add!!!!')
return a + b
def my_wrong_add(a, b):
print('my_wrong_add!!!!')
return a + b + 1
テストするためのコードは下記のとおりです。クラスを作ってその下にメソッドを足していくのが基本的な使い方です。
# tests/test_main.py
import pytest
from sample.main import my_add, my_wrong_add
class TestAdd:
def test_add(self):
assert my_add(1, 2) == 3
def test_wrong_add(self):
assert my_wrong_add(1, 2) == 3
クラスに分ける理由が良くわからなかったのですが、世の中のテスト達を見ているとどうもクラスごとにmarkを付けて、Linuxだったら実行する、Macだったら実行するなどの条件を追加する単位として使うようです。
実行は簡単でpytestコマンドを実行するだけです。
$ pytest .F [100%] =================================== FAILURES =================================== ____________________________ TestAdd.test_wrong_add ____________________________ self = <tests.test_main.TestAdd object at 0x7f617eab4650> def test_wrong_add(self): > assert my_wrong_add(1, 2) == 3 E assert 4 == 3 E + where 4 = my_wrong_add(1, 2) tests/test_main.py:9: AssertionError ----------------------------- Captured stdout call ----------------------------- my_wrong_add!!!! =========================== short test summary info ============================ FAILED tests/test_main.py::TestAdd::test_wrong_add - assert 4 == 3 1 failed, 1 passed in 0.03s
関数my_add()のテストは成功し、my_wrong_add()のテストは失敗します。意図通りですね。my_wrong_add()を修正すればテスト成功する様子も簡単に確認できるはずです。
$ pytest .. [100%] 2 passed in 0.00s
テストはスクリプト、テストクラス、関数を指定して部分的に実行できます。
#### スクリプトを指定 $ pytest tests/test_main.py .. [100%] 2 passed in 0.00s #### クラスを指定 $ pytest tests/test_main.py::TestAdd .. [100%] 2 passed in 0.00s #### 関数を指定 $ pytest tests/test_main.py::TestAdd::test_add . [100%] 1 passed in 0.00s
失敗するテストだけ何度も再実行するときに便利ですね。
どちらの関数もprint()しますが、失敗したテストの標準出力のみが表示され、成功したテストの標準出力は無視されます。もし成功したテストも見たければ-rAを指定してください。
$ pytest -rA .. [100%] ==================================== PASSES ==================================== _______________________________ TestAdd.test_add _______________________________ ----------------------------- Captured stdout call ----------------------------- my_add!!!! ____________________________ TestAdd.test_wrong_add ____________________________ ----------------------------- Captured stdout call ----------------------------- my_wrong_add!!!! =========================== short test summary info ============================ PASSED tests/test_main.py::TestAdd::test_add PASSED tests/test_main.py::TestAdd::test_wrong_add 2 passed in 0.00s
とりあえず基本的な使い方はこんなもんかなと思います。また気が向いたら書きます。