単体テストとJUNIT5

プログラミング開発において、テストフェーズは下記に大きく分けられます。


1.単体テスト 2.結合テスト 3.機能テスト 4.システムテスト 5.ユーザ受け入れテスト


テストの目的とはなんでしょうか。

バグを発見すること 品質を保証すること 品質を改善すること

バグを防ぐのはいつでもエンジニアの課題でしょう。

今回は、Seleniumの検証中でもあり、単体テストについて触れてみたいと思います。

単体テストとは

・クラスや関数などのプログラム単体でのテスト ・設計通りに動くかを検証 ・テスティングフレームワークを使ったテストプログラムで、メソッドなどの小さな単位で行うテスト ・個々の機能を正しく果たしているかどうかを検証するテスト

実装中段階の早期段階で、機能が仕様通りに実装されているかを確認することにより、開発の後工程で行われるテストに比べて早い段階でバグをつぶすことができます。

必要な理由


・問題の原因の特定や修正が容易。 ・開発全体のバグ修正コストを下げる ・コードの内容をよく理解している開発者によって、コード作成と同時か直後にテストケースが作成できる


単体テストの課題は


・開発者への負担 ・ある程度のスキルが必要 ・スケジュール的に厳しい


テストプログラムには、JUNITが利用されます。

JUNITとは


Java開発では多くのプロジェクトでオープンソースの「JUnit」が使われています。 JUnitJavaプログラム単体テスト用のフレームワークです。

共通のテストフレームワークをもつことで、他人のテストプログラムの修正を容易にします。

また、テストプログラムを記述するために、たくさんの知識を習得する必要はありません。数個の規則を学べばよいのです


JUNITの現状


単体テストの重要性は誰もが把握していますが、テストプログラミングに時間が取れない。 ・ユニットテストを行うのは原則としてプログラマです。専門の知識は必要ありませんが、 基礎的な知識やスキルはが必要となります。 ・HTMLやCSSについても、最低限の知識やスキルが必要。


問題点


JUnitを使った単体テストは、テストコードを書く必要があり。 ・テスト対象と同じくらい、またはそれ以上のコード量が必要 ・意図した通りにテストが動くかを確認するためにはデバッグが不可欠 ・単体テストにも慣れが必要


推奨される理由


・一度作成すればすばやくテスト可能 ・テストコードを標本とすることでバグ訂正が容易 ・IDEを使うことで、テストコードの再作成によって生じる手間を軽減または高速化 ・テストコードを見れば仕様がわかる


JUNIT4 から5へ

2017年にはJUnit5 がリリースされました。


・サポートされるJavaのバージョンは8です。今後は9にも対応します。 ・最初のハードルが高いため、直感的な仕様となっている。 ・JUnit 4とは互換性がない。 ・既存のテストを書き換えないほうがよい。 ・インストールは、Maven Centralにデプロイされています。


今後は


seleniumやselenideなどで自動化する動きがありますので、需要はますます上がるでしょう。


Selenium+Pythonインストールをインストールしたことある?

Seleniumとは、Webの自動テストのためのライブラリ。 Python版のSeleniumをインストールしたいと思います。

開発環境


ホストマシン

・Vagrant2.0.1 ・Windows 7 Home PremiumVagrant 1.7.2 ・VirtualBox 4.3.26-98988

ゲストマシン

CentOS Linux release 7.3.1611 (Core)

ソフトウェア

Python :3.5.4 ・JAVA:"1.8.0_151" ・chromedrive:2.3 ・Crome:62.0.3202.89 ・Selenium:3


EPELリポジトリのインストール

CentOSのパッケージは枯れたものが多いので、外部リポジトリを 追加することで新しいパッケージを利用できるようにします。


$sudo yum -y install epel-release


ChromeDriverのインストールの事前準備


$sudo yum -y install wget $sudo yum -y install unzip $wget https://chromedriver.storage.googleapis.com/2.33/ chromedriver_linux64.zip   

$sudo unzip chromedriver_linux64.zip $sudo mv chromedriver /usr/local/bin/ $sudo chown root:root /usr/local/bin/chromedriver   


Google Chromeのインストール  

参考URL: [CentOS7にChromeをインストール] (https://qiita.com/shadowhat/items/af6b973df43d75abfe8e)


/etc/yum.repos.d/google-chrome.repoでリポジトリファイルを設定。

sudo vi /etc/yum.repos.d/google.chrome.repo

Viで内容を入力

[google-chrome] name=google-chrome baseurl=http://dl.google.com/linux/chrome/rpm/stable/$basearch enabled=1 gpgcheck=1 gpgkey=https://dl-ssl.google.com/linux/linux_signing_key.pub

インストールする

sudo yum -y install google-chrome-stable

Chromedriverは2.31以降をインストールしてください。 2.30以前ですと、seleniumでsend_keysが使えない問題が 発生していたのですが、2.31でこの問題が解消しています!


PIPのインストール方法


python-devel を入れる

sudo yum -y install python-devel

python-pip をインストールする

sudo yum -y install python-pip  

パッケージをアップデートする。

sudo yum -y update


JAVAのインストール


sudo yum install -y java-1.8.0-openjdk.x86_64 sudo yum install -y java-1.8.0-openjdk-devel.x86_64


pythonを2系から3系にアップさせる。


pyenvをインストールすることで複数のバージョンのpythonを共存させて 簡単に切り替えることができます。

$ git clone https://github.com/yyuu/pyenv.git ~/.pyenv bash_profileに環境変数を記述します。

$ vim .bash_profile 下記を追記 $ pyenv export PYENV_ROOT="$HOME/.pyenv" export PATH="$PYENV_ROOT/bin:$PATH" eval "$(pyenv init -)"

.bash_profileを読み込ませる  

念のためコマンドを読む

export PYENV_ROOT="$HOME/.pyenv" export PATH="$PYENV_ROOT/bin:$PATH"

インストールできるバージョンを一覧表示

pyenv install --list

3.5.4をインストール

$ pyenv install 3.5.4   pythonのバージョンを確認  

$ python --version Python 2.7.5

python3.5.1に切り替え

$ pyenv global 3.5.4 $ pyenv rehash $ python --version Python 3.5.4


Seleniumのインストール


pip install selenium


バージョンの確認方法


java -version google-chrome -version python --version


実行


python test.py

まとめ

ChromeDriverの実行ファイルは、ご利用のGoogle Chrome のバージョンに合わせて適切な組み合わせを選ぶ必要が有ります。 また、Google Chrome自体は自動アップデートしていくので、 開発環境のChromeDriverも追随していく必要が有ります。


標的型攻撃メールの対策はAWSでできるのか?

標的型メールが流行っている昨今、特定のメールからしか受信をしないのであれば、メールドメイン単位でフィルタリングが出来るのだろうか。

特に大手企業のドメインは有名であり、中国からもよく狙われています。

SESでAWSを導入すればよいが、EC2でのMTAを実装を考えており、検討してみた。

AWS構成】

・ELB + EC2 + RDS ・EC2からメール受信時に、メールサーバのドメイン名 (FQDN)でアクセス権限をかける ・EC2にMTAをもつ

本来であれば、IPでの制限については、セキュリティグループとNACLで可能であり、 こちらで制限できるか、確認した。

セキュリティグループとNACLの違いは?

簡単にいうと、セキュリティグループはインスタンスレベルで動作。

NACLは、サブネットレベルで動作で動作。

比較をして見ましょう。

セキュリティグループ NACL
インスタンスレベルで動作 サブネットレベルで動作
ステートフル: ルールに関係なく、返されたトラフィックが自動的に許可 ステートレス: 返されたトラフィックがルールによって明示的に許可
該当のトラフィックを許可する前に全ての許可設定を評価 該当のトラフィックを許可するとき、ルール番号順にACLのルールを処理
インスタンスを起動するときのみ指定 サブネット内で起動した全てのインスタンスに対して自動的に適応

セキュリティグループはAWSに触れるひとであれば、当たり前の知識であるかもしれませんが、NACLはあまり設定をすることはないかもしれませので、もう少し深く説明しましょう。

NACLについて

・NACLは、ルールに番号付けしたリスト。 ・ACLに関連づけられたサブネットの入りと出のトラフィックのに対して小さな番号順に許可される。 ・インバウンドまたはアウトバウンドのトラフィックについて、個別に許可と拒否を設定 ・VPCは自動的にデフォルトACLに属します。初期設定で全ての入りと出のトラフィックを許可 ・任意にカスタマイズしたACLを追加可能 ・カスタムACLは、初期設定として全ての入りと出のトラフィックを拒否 ・許可ルールを追加することで通信可能 ・どのサブネットもACLを関連づける必要があり。 ・サブネットにACLを指定しない場合には、デフォルトACLが適応されます。 ・ACLはステートレスです。レスポンスの通信を許可する必要あり

フィルタできない通信は?

では、セキュリティグループとNACLで防げない通信はあるのでしょうか。

セキュリティグループとNACLは、リンクローカルアドレスに関するトラフィックをフィルタすることができません。 リンクローカルアドレスとは、VPC内で動いているDNSサーバー、DHCPAmazon EC2指定のメタデータです。 もし、これらの通信をブロックしたければ、EC2内にオリジナルのファイアウォールを設定すればブロックすることができます。

それでは本題であるFQDNの通信は?その他のWAFなどを用いてでできるだろうか?

残念ながら、 AWS サービスの機能を利用した方法では、このような要件を満たす方法はありませんでした。

このため実現方法は、セキュリティグループやネットワーク ACL を更新するスクリプトを作成するか、インスタンス内の iptables などで実施する必要があります。

iptabelsはCENTOS7では使われない技術になってきておりますが、Linuxで最も使われているファイアウォールです。

ドメインで止められないのであれば

それでは下記のように設定しましょう。

似たようなIPなので傾向を見るため、一定期間メールログからアクセス元のIPを抽出する。

それらを並べてみると、大体近いIPアドレスが多いのに気づく。

IP業者が使うであろうアドレスを含む広い範囲を遮断すればよい。

「国/地域別IPアドレス割当数一覧」というサイトを利用する。

数百個あるIPアドレスも複数のグループに分けられるはずだ。

iptabelsで下記のコマンドで設定する。 複数のコマンドをそれぞれ実行。

iptables -I INPUT 2 -s xx.xxx.xxx.xxx/12 -j DROP

そのあとは、リスタートすればよろし。

まとめ

AWSに関わらず、標的型メールが流行っている昨今、特定のメールドメインのブロックをオンプレのファイアウォールでも設定の可能・不可能があった。

AWSでは今は設定できないことではあるが、需要は多いと考えられるので、ぜひ実装してほしい。