前回に引き続き、
4番目の仕様「商品コードを指定して、カートに入っている数量を取得できる」
次は4番目の仕様
商品コードを指定して、カートに入っている数量を取得できる
です。ここでは、
- Cartオブジェクトを作成した直後は0を返す
- 商品コード
「001」 を1個追加すると、 getAmount('001')は1を返す - カートに入っていない商品が指定された場合、
数量として0を返す
テストを追加したテストケースは次のようになりました。
<?php
require_once 'PHPUnit/Framework.php';
require_once 'Cart.php';
class CartTest extends PHPUnit_Framework_TestCase
{
public function testInitCart() {
$cart = new Cart();
$this->assertTrue(is_array($cart->getItems()));
$this->assertEquals(0, count($cart->getItems()));
}
public function testAdd() {
$cart = new Cart();
$this->assertTrue($cart->add('001', 1));
$this->assertTrue($cart->add('001', 0));
$this->assertTrue($cart->add('001', -1));
}
public function testAddNotNumeric() {
$cart = new Cart();
try {
$cart->add('001', 'string');
} catch (UnexpectedValueException $e) {
return;
}
$this->fail();
}
public function testAddFloat() {
$cart = new Cart();
try {
$cart->add('001', 1.5);
} catch (UnexpectedValueException $e) {
return;
}
$this->fail();
}
public function testGetAmount() {
$cart = new Cart();
$this->assertEquals(0, $cart->getAmount('001'));
$cart->add('001', 1);
$this->assertEquals(1, $cart->getAmount('001'));
$this->assertEquals(0, $cart->getAmount('999'));
}
}
<?php
class Cart
{
public function getItems() {
return array();
}
public function add($item_cd, $amount) {
if (preg_match('/^-?\d+$/', $amount)) {
return true;
} else {
throw new UnexpectedValueException('Invalid amount');
}
}
public function getAmount($item_cd) {
}
}
$ phpunit CartTest PHPUnit 3.1.7 by Sebastian Bergmann. ....F Time: 0 seconds There was 1 failure: 1) testGetAmount(CartTest) Failed asserting that <null> matches expected value <integer:0>. /home/shimooka/public_html/gihyo.jp/01.phpunit/CartTest.php:43 FAILURES! Tests: 5, Failures: 1. $
さて、
まず、
<?php
class Cart
{
private $items;
public function __construct() {
$this->items = array();
}
public function getItems() {
return array();
}
public function add($item_cd, $amount) {
if (preg_match('/^-?\d+$/', $amount)) {
if (!isset($this->items[$item_cd])) {
$this->items[$item_cd] = 0;
}
$this->items[$item_cd] += (int)$amount;
return true;
} else {
throw new UnexpectedValueException('Invalid amount');
}
}
public function getAmount($item_cd) {
if (isset($this->items[$item_cd])) {
return $this->items[$item_cd];
} else {
return 0;
}
}
}
テストを実行してみましょう。
$ phpunit CartTest PHPUnit 3.1.7 by Sebastian Bergmann. ..... Time: 0 seconds OK (5 tests) $
今までのテストを含め、
<?php
require_once 'PHPUnit/Framework.php';
require_once 'Cart.php';
class CartTest extends PHPUnit_Framework_TestCase
{
public function testInitCart() {
$cart = new Cart();
$this->assertTrue(is_array($cart->getItems()));
$this->assertEquals(0, count($cart->getItems()));
}
public function testAdd() {
$cart = new Cart();
$this->assertTrue($cart->add('001', 1));
$this->assertTrue($cart->add('001', 0));
$this->assertTrue($cart->add('001', -1));
}
public function testAddNotNumeric() {
$cart = new Cart();
try {
$cart->add('001', 'string');
} catch (UnexpectedValueException $e) {
return;
}
$this->fail();
}
public function testAddFloat() {
$cart = new Cart();
try {
$cart->add('001', 1.5);
} catch (UnexpectedValueException $e) {
return;
}
$this->fail();
}
public function testGetAmount() {
$cart = new Cart();
$this->assertEquals(0, $cart->getAmount('001'));
$cart->add('001', 1);
$this->assertEquals(1, $cart->getAmount('001'));
$this->assertEquals(0, $cart->getAmount('999'));
$cart->add('002', 1);
$this->assertEquals(1, $cart->getAmount('001'));
$this->assertEquals(1, $cart->getAmount('002'));
$cart->add('001', -1);
$this->assertEquals(0, $cart->getAmount('001'));
$this->assertEquals(1, $cart->getAmount('002'));
}
}
$ phpunit CartTest PHPUnit 3.1.7 by Sebastian Bergmann. ..... Time: 0 seconds OK (5 tests) $
大丈夫そうです。これで4番目の仕様も実装完了とします。
5番目の仕様「すべての商品コードと数量をまとめて取得できる」
1番目の仕様を実装する際に追加したgetItemsメソッドですが、
- カートに複数の商品を追加した場合の商品種の数
- getItemsメソッドで取得したハッシュの内容のチェック
テストを追加したテストケースは次のようになりました。
<?php
require_once 'PHPUnit/Framework.php';
require_once 'Cart.php';
class CartTest extends PHPUnit_Framework_TestCase
{
public function testInitCart() {
$cart = new Cart();
$this->assertTrue(is_array($cart->getItems()));
$this->assertEquals(0, count($cart->getItems()));
}
public function testAdd() {
$cart = new Cart();
$this->assertTrue($cart->add('001', 1));
$this->assertTrue($cart->add('001', 0));
$this->assertTrue($cart->add('001', -1));
}
public function testAddNotNumeric() {
$cart = new Cart();
try {
$cart->add('001', 'string');
} catch (UnexpectedValueException $e) {
return;
}
$this->fail();
}
public function testAddFloat() {
$cart = new Cart();
try {
$cart->add('001', 1.5);
} catch (UnexpectedValueException $e) {
return;
}
$this->fail();
}
public function testGetAmount() {
$cart = new Cart();
$this->assertEquals(0, $cart->getAmount('001'));
$cart->add('001', 1);
$this->assertEquals(1, $cart->getAmount('001'));
$this->assertEquals(0, $cart->getAmount('999'));
$cart->add('002', 1);
$this->assertEquals(1, $cart->getAmount('001'));
$this->assertEquals(1, $cart->getAmount('002'));
$cart->add('001', -1);
$this->assertEquals(0, $cart->getAmount('001'));
$this->assertEquals(1, $cart->getAmount('002'));
}
public function testGetItems() {
$cart = new Cart();
$cart->add('001', 3);
$this->assertEquals(1, count($cart->getItems()));
$cart->add('002', 2);
$this->assertEquals(2, count($cart->getItems()));
$items = $cart->getItems();
$this->assertEquals(3, $items['001']);
$this->assertEquals(2, $items['002']);
}
}
$ phpunit CartTest PHPUnit 3.1.7 by Sebastian Bergmann. .....F Time: 0 seconds There was 1 failure: 1) testGetItems(CartTest) Failed asserting that <integer:0> matches expected value <integer:1>. /home/shimooka/public_html/gihyo.jp/CartTest.php:60 FAILURES! Tests: 6, Failures: 1. $
おっと。getItemsメソッドは、
<?php
class Cart
{
private $items;
public function __construct() {
$this->items = array();
}
public function getItems() {
return $this->items;
}
public function add($item_cd, $amount) {
if (preg_match('/^-?\d+$/', $amount)) {
if (!isset($this->items[$item_cd])) {
$this->items[$item_cd] = 0;
}
$this->items[$item_cd] += (int)$amount;
return true;
} else {
throw new UnexpectedValueException('Invalid amount');
}
}
public function getAmount($item_cd) {
if (isset($this->items[$item_cd])) {
return $this->items[$item_cd];
} else {
return 0;
}
}
}
$ phpunit CartTest PHPUnit 3.1.7 by Sebastian Bergmann. ...... Time: 0 seconds OK (6 tests) $
6番目の仕様「クリアすると、カートは初期状態になる」
次は最後の仕様
クリアすると、カートは初期状態になる
です。仕様に対するテストはどの様になるでしょうか?
- clearメソッドを呼び出すと、
コンストラクタを呼び出した場合と同様の動作をする
ということで良さそうです。早速テストケースにテストを追加し、
<?php
require_once 'PHPUnit/Framework.php';
require_once 'Cart.php';
class CartTest extends PHPUnit_Framework_TestCase
{
public function testInitCart() {
$cart = new Cart();
$this->assertTrue(is_array($cart->getItems()));
$this->assertEquals(0, count($cart->getItems()));
}
public function testAdd() {
$cart = new Cart();
$this->assertTrue($cart->add('001', 1));
$this->assertTrue($cart->add('001', 0));
$this->assertTrue($cart->add('001', -1));
}
public function testAddNotNumeric() {
$cart = new Cart();
try {
$cart->add('001', 'string');
} catch (UnexpectedValueException $e) {
return;
}
$this->fail();
}
public function testAddFloat() {
$cart = new Cart();
try {
$cart->add('001', 1.5);
} catch (UnexpectedValueException $e) {
return;
}
$this->fail();
}
public function testGetAmount() {
$cart = new Cart();
$this->assertEquals(0, $cart->getAmount('001'));
$cart->add('001', 1);
$this->assertEquals(1, $cart->getAmount('001'));
$this->assertEquals(0, $cart->getAmount('999'));
$cart->add('002', 1);
$this->assertEquals(1, $cart->getAmount('001'));
$this->assertEquals(1, $cart->getAmount('002'));
$cart->add('001', -1);
$this->assertEquals(0, $cart->getAmount('001'));
$this->assertEquals(1, $cart->getAmount('002'));
}
public function testGetItems() {
$cart = new Cart();
$cart->add('001', 3);
$this->assertEquals(1, count($cart->getItems()));
$cart->add('002', 2);
$this->assertEquals(2, count($cart->getItems()));
$items = $cart->getItems();
$this->assertEquals(3, $items['001']);
$this->assertEquals(2, $items['002']);
}
public function testClearCart() {
$cart = new Cart();
$cart->add('001', 1);
$cart->add('002', 2);
$cart->add('003', 3);
$cart->clear();
$this->assertTrue(is_array($cart->getItems()));
$this->assertEquals(0, count($cart->getItems()));
}
}
<?php
class Cart
{
private $items;
public function __construct() {
$this->items = array();
}
public function getItems() {
return $this->items;
}
public function add($item_cd, $amount) {
if (preg_match('/^-?\d+$/', $amount)) {
if (!isset($this->items[$item_cd])) {
$this->items[$item_cd] = 0;
}
$this->items[$item_cd] += (int)$amount;
return true;
} else {
throw new UnexpectedValueException('Invalid amount');
}
}
public function getAmount($item_cd) {
if (isset($this->items[$item_cd])) {
return $this->items[$item_cd];
} else {
return 0;
}
}
public function clear() {
}
}
$ phpunit CartTest PHPUnit 3.1.7 by Sebastian Bergmann. ......F Time: 0 seconds There was 1 failure: 1) testClearCart(CartTest) Failed asserting that <integer:3> matches expected value <integer:0>. /home/shimooka/public_html/gihyo.jp/CartTest.php:76 FAILURES! Tests: 7, Failures: 1. $
それでは、
<?php
class Cart
{
private $items;
public function __construct() {
$this->items = array();
}
public function getItems() {
return $this->items;
}
public function add($item_cd, $amount) {
if (preg_match('/^-?\d+$/', $amount)) {
if (!isset($this->items[$item_cd])) {
$this->items[$item_cd] = 0;
}
$this->items[$item_cd] += (int)$amount;
return true;
} else {
throw new UnexpectedValueException('Invalid amount');
}
}
public function getAmount($item_cd) {
if (isset($this->items[$item_cd])) {
return $this->items[$item_cd];
} else {
return 0;
}
}
public function clear() {
$this->items = array();
}
}
$ phpunit CartTest PHPUnit 3.1.7 by Sebastian Bergmann. ....... Time: 0 seconds OK (7 tests) $
テストにパスしました。
<?php
class Cart
{
private $items;
public function __construct() {
$this->clear();
}
public function getItems() {
return $this->items;
}
public function add($item_cd, $amount) {
if (preg_match('/^-?\d+$/', $amount)) {
if (!isset($this->items[$item_cd])) {
$this->items[$item_cd] = 0;
}
$this->items[$item_cd] += (int)$amount;
return true;
} else {
throw new UnexpectedValueException('Invalid amount');
}
}
public function getAmount($item_cd) {
if (isset($this->items[$item_cd])) {
return $this->items[$item_cd];
} else {
return 0;
}
}
public function clear() {
$this->items = array();
}
}
$ phpunit CartTest PHPUnit 3.1.7 by Sebastian Bergmann. ....... Time: 0 seconds OK (7 tests) $
テスト結果も問題ないようです。
不足している仕様とテストを追加する
さて、
- カートに入っている商品の数量は0以上PHP_
INT_ MAX以下 - 数量の上限を超過した場合、
OutOfRangeExceptionを投げる - 数量の下限を超過した場合、
数量は0になる
現在の仕様では
- 数量が下限もしくは下限を超過した場合、
その商品はカートから取り除かれる
となります。
それでは、
<?php
require_once 'PHPUnit/Framework.php';
require_once 'Cart.php';
class CartTest extends PHPUnit_Framework_TestCase
{
public function testInitCart() {
$cart = new Cart();
$this->assertTrue(is_array($cart->getItems()));
$this->assertEquals(0, count($cart->getItems()));
}
public function testAdd() {
$cart = new Cart();
$this->assertTrue($cart->add('001', 1));
$this->assertTrue($cart->add('001', 0));
$this->assertTrue($cart->add('001', -1));
}
public function testAddNotNumeric() {
$cart = new Cart();
try {
$cart->add('001', 'string');
} catch (UnexpectedValueException $e) {
return;
}
$this->fail();
}
public function testAddFloat() {
$cart = new Cart();
try {
$cart->add('001', 1.5);
} catch (UnexpectedValueException $e) {
return;
}
$this->fail();
}
public function testGetAmount() {
$cart = new Cart();
$this->assertEquals(0, $cart->getAmount('001'));
$cart->add('001', 1);
$this->assertEquals(1, $cart->getAmount('001'));
$this->assertEquals(0, $cart->getAmount('999'));
$cart->add('002', 1);
$this->assertEquals(1, $cart->getAmount('001'));
$this->assertEquals(1, $cart->getAmount('002'));
$cart->add('001', -1);
$this->assertEquals(0, $cart->getAmount('001'));
$this->assertEquals(1, $cart->getAmount('002'));
}
public function testGetItems() {
$cart = new Cart();
$cart->add('001', 3);
$this->assertEquals(1, count($cart->getItems()));
$cart->add('002', 2);
$this->assertEquals(2, count($cart->getItems()));
$items = $cart->getItems();
$this->assertEquals(3, $items['001']);
$this->assertEquals(2, $items['002']);
}
public function testClearCart() {
$cart = new Cart();
$cart->add('001', 1);
$cart->add('002', 2);
$cart->add('003', 3);
$cart->clear();
$this->assertTrue(is_array($cart->getItems()));
$this->assertEquals(0, count($cart->getItems()));
}
public function testAddUpperLimit() {
$cart = new Cart();
$cart->add('001', PHP_INT_MAX);
try {
$cart->add('001', 1);
} catch (OutOfRangeException $e) {
return;
}
$this->fail();
}
public function testAddUnderLimit() {
$cart = new Cart();
$cart->add('001', 1);
$this->assertEquals(1, count($cart->getItems()));
$cart->add('001', -1);
$this->assertEquals(0, count($cart->getItems()));
$cart->clear();
$cart->add('001', 1);
$this->assertEquals(1, count($cart->getItems()));
$cart->add('001', -2);
$this->assertEquals(0, count($cart->getItems()));
}
public function testAddRemove() {
$cart = new Cart();
$cart->add('001', 2);
$cart->add('002', 3);
$this->assertEquals(2, count($cart->getItems()));
$cart->add('001', -2);
$items = $cart->getItems();
$this->assertEquals(1, count($items));
$this->assertFalse(isset($items['001']));
$this->assertEquals(3, $items['002']);
$cart->add('002', -3);
$items = $cart->getItems();
$this->assertEquals(0, count($items));
$this->assertFalse(isset($items['001']));
$this->assertFalse(isset($items['002']));
}
}
$ phpunit CartTest PHPUnit 3.1.7 by Sebastian Bergmann. .......FFF Time: 0 seconds There were 3 failures: 1) testAddUpperLimit(CartTest) /home/shimooka/public_html/gihyo.jp/CartTest.php:87 2) testAddUnderLimit(CartTest) Failed asserting that <integer:1> matches expected value <integer:0>. /home/shimooka/public_html/gihyo.jp/CartTest.php:95 3) testAddRemove(CartTest) Failed asserting that <integer:2> matches expected value <integer:1>. /home/shimooka/public_html/gihyo.jp/CartTest.php:112 FAILURES! Tests: 10, Failures: 3. $
テストが通るように、
<?php
class Cart
{
private $items;
public function __construct() {
$this->clear();
}
public function getItems() {
return $this->items;
}
public function add($item_cd, $amount) {
if (preg_match('/^-?\d+$/', $amount)) {
if (!isset($this->items[$item_cd])) {
$this->items[$item_cd] = 0;
}
$this->items[$item_cd] += (int)$amount;
if ($this->items[$item_cd] > PHP_INT_MAX) {
throw new OutOfRangeException('the amount exceeded PHP_INT_MAX');
}
if ($this->items[$item_cd] <= 0) {
unset($this->items[$item_cd]);
}
return true;
} else {
throw new UnexpectedValueException('Invalid amount');
}
}
public function getAmount($item_cd) {
if (isset($this->items[$item_cd])) {
return $this->items[$item_cd];
} else {
return 0;
}
}
public function clear() {
$this->items = array();
}
}
$ phpunit CartTest PHP Parse error: syntax error, unexpected T_PUBLIC in /home/shimooka/public_ht ml/gihyo.jp/Cart.php on line 29 Parse error: syntax error, unexpected T_PUBLIC in /home/shimooka/public_html/gi hyo.jp/Cart.php on line 29 [shimooka@centos gihyo.jp]$ phpunit CartTest PHPUnit 3.1.7 by Sebastian Bergmann. .......... Time: 0 seconds OK (10 tests) $
うまくいきました。
テストのコードカバー率を確認する
さて、
$ su - # pecl install -a xdebug # echo "zend_extension=/usr/local/lib/php5/lib/php/extensions/no-debug-non-zts-20060613/xdebug.so" >> /usr/local/lib/php5/ini/5.2.3/php.ini #
インストール後、
$ php -i | grep -i "xdebug support" xdebug support => enabled #
また、
$ phpunit --help PHPUnit 3.1.7 by Sebastian Bergmann. Usage: phpunit [switches] UnitTest [UnitTest.php] --log-graphviz <file> Log test execution in GraphViz markup. --log-json <file> Log test execution in JSON format. --log-tap <file> Log test execution in TAP format to file. --log-xml <file> Log test execution in XML format to file. --coverage-xml <file> Write code coverage information in XML format. --report <dir> Generate combined test/coverage report in HTML format. --test-db-dsn <dsn> DSN for the test database. --test-db-log-rev <r> Revision information for database logging. --test-db-log-info ... Additional information for database logging. --testdox-html <file> Write agile documentation in HTML format to file. --testdox-text <file> Write agile documentation in Text format to file. --filter <pattern> Filter which tests to run. --loader <loader> TestSuiteLoader implementation to use. --repeat <times> Runs the test(s) repeatedly. --tap Report test execution progress in TAP format. --testdox Report test execution progress in TestDox format. --no-syntax-check Disable syntax check of test source files. --stop-on-failure Stop execution upon first error or failure. --verbose Output more verbose information. --wait Waits for a keystroke after each test. --skeleton Generate skeleton UnitTest class for Unit in Unit.php. --help Prints this usage information. --version Prints the version and exits. -d key[=value] Sets a php.ini value. $
Xdebugを正しくインストールできたら、
$ phpunit --report ./report CartTest PHPUnit 3.1.7 by Sebastian Bergmann. .......... Time: 0 seconds OK (10 tests) Generating report, this may take a moment.sh: neato: command not found $
実行後、

また、

これらの結果を見ると、
Cartクラスとテストケースのリファクタリング
最後の修正でaddメソッドのネストが若干深くなってしまいましたので、
テストが自動化されていない場合、
前置きがちょっと長くなりましたが、
<?php
class Cart
{
private $items;
public function __construct() {
$this->clear();
}
public function getItems() {
return $this->items;
}
public function add($item_cd, $amount) {
if (!preg_match('/^-?\d+$/', $amount)) {
throw new UnexpectedValueException('Invalid amount');
}
if (!isset($this->items[$item_cd])) {
$this->items[$item_cd] = 0;
}
$this->items[$item_cd] += (int)$amount;
if ($this->items[$item_cd] > PHP_INT_MAX) {
throw new OutOfRangeException('the amount exceeded PHP_INT_MAX');
}
if ($this->items[$item_cd] <= 0) {
unset($this->items[$item_cd]);
}
return true;
}
public function getAmount($item_cd) {
if (isset($this->items[$item_cd])) {
return $this->items[$item_cd];
} else {
return 0;
}
}
public function clear() {
$this->items = array();
}
}
リファクタリング後、
$ phpunit CartTest PHPUnit 3.1.7 by Sebastian Bergmann. .......... Time: 0 seconds OK (10 tests) $
ついでに、
これまで作成したすべてのテストでは、
メソッド | 意味 |
---|---|
void setUp() | これをオーバーライドして、 |
void tearDown() | これをオーバーライドして、 |
それでは、
<?php
require_once 'PHPUnit/Framework.php';
require_once 'Cart.php';
class CartTest extends PHPUnit_Framework_TestCase
{
protected $cart;
protected function setUp() {
$this->cart = new Cart();
}
public function testInitCart() {
$this->assertTrue(is_array($this->cart->getItems()));
$this->assertEquals(0, count($this->cart->getItems()));
}
public function testAdd() {
$this->assertTrue($this->cart->add('001', 1));
$this->assertTrue($this->cart->add('001', 0));
$this->assertTrue($this->cart->add('001', -1));
}
public function testAddNotNumeric() {
try {
$this->cart->add('001', 'string');
} catch (UnexpectedValueException $e) {
return;
}
$this->fail();
}
public function testAddFloat() {
try {
$this->cart->add('001', 1.5);
} catch (UnexpectedValueException $e) {
return;
}
$this->fail();
}
public function testGetAmount() {
$this->assertEquals(0, $this->cart->getAmount('001'));
$this->cart->add('001', 1);
$this->assertEquals(1, $this->cart->getAmount('001'));
$this->assertEquals(0, $this->cart->getAmount('999'));
$this->cart->add('002', 1);
$this->assertEquals(1, $this->cart->getAmount('001'));
$this->assertEquals(1, $this->cart->getAmount('002'));
$this->cart->add('001', -1);
$this->assertEquals(0, $this->cart->getAmount('001'));
$this->assertEquals(1, $this->cart->getAmount('002'));
}
public function testGetItems() {
$this->cart->add('001', 3);
$this->assertEquals(1, count($this->cart->getItems()));
$this->cart->add('002', 2);
$this->assertEquals(2, count($this->cart->getItems()));
$items = $this->cart->getItems();
$this->assertEquals(3, $items['001']);
$this->assertEquals(2, $items['002']);
}
public function testClearCart() {
$this->cart->add('001', 1);
$this->cart->add('002', 2);
$this->cart->add('003', 3);
$this->cart->clear();
$this->assertTrue(is_array($this->cart->getItems()));
$this->assertEquals(0, count($this->cart->getItems()));
}
public function testAddUpperLimit() {
$this->cart->add('001', PHP_INT_MAX);
try {
$this->cart->add('001', 1);
} catch (OutOfRangeException $e) {
return;
}
$this->fail();
}
public function testAddUnderLimit() {
$this->cart->add('001', 1);
$this->assertEquals(1, count($this->cart->getItems()));
$this->cart->add('001', -1);
$this->assertEquals(0, count($this->cart->getItems()));
$this->cart->clear();
$this->cart->add('001', 1);
$this->assertEquals(1, count($this->cart->getItems()));
$this->cart->add('001', -2);
$this->assertEquals(0, count($this->cart->getItems()));
}
public function testAddRemove() {
$this->cart->add('001', 2);
$this->cart->add('002', 3);
$this->assertEquals(2, count($this->cart->getItems()));
$this->cart->add('001', -2);
$items = $this->cart->getItems();
$this->assertEquals(1, count($items));
$this->assertFalse(isset($items['001']));
$this->assertEquals(3, $items['002']);
$this->cart->add('002', -3);
$items = $this->cart->getItems();
$this->assertEquals(0, count($items));
$this->assertFalse(isset($items['001']));
$this->assertFalse(isset($items['002']));
}
}
phpunitコマンドを実行して問題がないことを確認します。
$ phpunit CartTest PHPUnit 3.1.7 by Sebastian Bergmann. .......... Time: 0 seconds OK (10 tests) $
これで完成です。
次回は、