Hashman's Blog

自動測試與 TDD 實務開發(使用 C#) by 91 哥 Day1

| Comments

今天第一天上 91 哥的課,也是第一次,看到整間教室坐滿就知道 91 哥的名氣跟課程內容的豐富度一定很高,課程中的學員也有蠻多都是已經上過 91 哥課程的老學員又回來在聽的,隨著時間的增長,課程中的實務案例與經驗分享也更為豐富。

前景提要

  • 在 KKBOX 其實已經有一定的 Unit Test 與 CI 自動化的導入機制,所以其實在上這門課以前,我就已經有不少的測試開發經驗,雖說大部分都還是撰寫 Unit Test ,但對於 TDD 也是有一定的基礎在。
  • 91 哥上課使採用 C# 上課,上課前 91 哥都會提供相當仔細的課程環境建設,如果你本身有在寫 C# 那恭喜你在這邊應該是沒有任何問題的,但如果你是 Mac or 沒有寫過 C# 的開發者那 ... 你應該在於建置環境上面需要多花點心力處理,以下提供幾個朋友實際安裝環境所會費的時間參考。
    • Mac + Virtual Box + Visual Studio(Full install) 在 SSD 上面跑約需要安裝 1.5 hr 。
    • Mac + Virtual Box + Visual Studio(上課所需的內容) 在 SD 上面跑約需要安裝 2.5 hr 。
  • 如果是用 C# 上課對於一個非 C# 的開發者會不會有困難呢?
    • 以我的狀況,我是 PHP 的開發者,平常是使用 PHPStorm 進行開發,對於 IDE 並不陌生,但是面對號稱地表最強的 IDE Visual Studio 說真的還是需要花點時間去習慣。
    • 至於 Code 會不會看不懂?我個人是覺得不會,只是 C# 有些語法上面是需要去習慣一下的。
  • 如果不是開發者像是 PM or Manager 去上這門課適合嗎?
    • 因為 91 哥上課會有大量的 workshop 需要實際去寫 code 進行相關測試,設計觀念與寫 Code 的比例大約是 6:4 吧,我是覺得還是會有收穫的,但可能在於寫 Code 進行測試上面可能稍有些辛苦。

課程重點

  1. 不是教你寫測試程式,而是教你開發跟設計
  2. 如何透過測試同時達到測試方法與測試文件
  3. 如何開發出更為穩定更為安心可以早早下班洗洗睡的 Code

有趣的上課方式

  1. 生動活潑的上課方式
    • 上課會採用分組活動來進行討論與分享。
    • 記點獎勵來激勵大家多多回答與發問。
    • 有問必達,可以於上課中隨時提出問題 91 哥都會耐心的解答,或是也可以利用備忘錄或是下課詢問的方式也可以獲得你要的答案 。
  2. 學習地圖與強調學習重點
    • 上課一開始就將 TDD Skill Tree 整個展開給學員們看,非常明瞭三天的學習方向、學習步驟與關連。
    • 本次開始提供課前講義(填空版與答案版),填空版主要為複習使用,可以知道空格的地方都是上課的重點,答案版可以隨時尋找答案。
  3. 實戰演練
    • 透過 Lab 的題目(原始題目、答案與步驟)進行操作,更可以針對不同的情境去撰寫自己的測試方法。
    • 透過老師提供的步驟說明,在自己回家後如果對於 Lab 有不清楚的時候可以翻開步驟一步一步的跟著進行操練。

了解實務上所遇到的問題與其解法

雖說 KKBOX 已經是一個已經有導入自動化測試開發的公司,但還是有需多的專案都是 0 測試的,如果將這些 0 測試的專案開始導入測試也是一個 Big Step 。

在實務上面常常會遇到測試對象與外部服務相依的狀況,應該要將這些外部服務切斷進而達到測試的獨立性。

常常也會遇到測試覺得複雜且不容易,也有可能說明了測試的對象並非為最小的測試單元或真的這個 Method 的業務邏輯相當複雜,進而可能需要進行 Refactor 或是確認需求等。

心得

在上課前總是會覺得,測試真的很麻煩,寫測試會增加我們的開發時間,但上完第一週的課程後,我了解了掌握開發的技巧、方法與順序,了解開發的重點,其實會發現測試一點都不花時間,掌握問題並且解決問題,開發出更有信心且穩定的程式碼是我們該邁向的目標。

期待未來兩週的課程。

PHP "..." operator 使用方式

| Comments

今天發現一個很酷的 php 5.6 以後的 feature

直接 show code 比較快

<?php

$string = "Controller@home";

test(...explode("@", $string));

function test($controller_name, $funciton_name)
{
    var_dump($controller_name, $funciton_name);
}

// print result
// string(10) "Controller"
// string(4) "home"

這個 operator 會直接將 explode 出來的 array 直接依序的放入 function 中

GitHub 也支援 Rebase Pull Request 了

| Comments

今天看到 GitHub 發出開始支援 Rebase Pull Request 詳細可以參考這裡

稍微小玩了一下

  1. 先對 push 一個 feature branch

  2. 開啟一個新的 Pull Request

  3. 開啟完之後會長這樣

  4. 選擇「Rebase and merge」

  5. Merge 完成

對於希望 tree 比較漂亮的人應該蠻喜愛這個功能的

MySQL 5.7 新增 JSON Data type

| Comments

於 MySQL 5.7 版正式加上 JSON 這個 Data Type 詳細可以參考

Create 與 Insert 的用法

mysql> CREATE TABLE t1 (jdoc JSON);
Query OK, 0 rows affected (0.20 sec)

mysql> INSERT INTO t1 VALUES('{"key1": "value1", "key2": "value2"}');
Query OK, 1 row affected (0.01 sec)

Select 的用法

mysql> SELECT JSON_TYPE('["a", "b", 1]');
+----------------------------+
| JSON_TYPE('["a", "b", 1]') |
+----------------------------+
| ARRAY                      |
+----------------------------+

mysql> SELECT JSON_TYPE('"hello"');
+----------------------+
| JSON_TYPE('"hello"') |
+----------------------+
| STRING               |
+----------------------+

Laravel Mail 筆記

| Comments

透過 blade email template 寄 email

$user = User::find(1); // user information

Mail::send('emails.register', compact('user'), function (message) {
    $message->from([from user email account], [from user nickname])
            ->to([receiver email account], [receiver name])
            ->subject('This is email title');
});

不透過 blade email template 寄 email

$user = User::find(1); // user information
$body = 'Something you want to email';

Mail::send([], [], function (message) use($body) {
    $message->from([from user email account], [from user nickname])
            ->to([receiver email account], [receiver name])
            ->subject('This is email title')
            ->setBody($body, 'text/html');
});

如果沒有想要以 html 的格式寄出,可以將 'text/html' 拿掉

參考文件

Git 常用指令

| Comments

整理一下 git 比較常用的一些指令

git

如何使用 git 縮寫

> vim ~/.gitconfig

# 加上下面內容
[alias]
      st = status
      co = checkout
      br = branch
      up = rebase
      ci = commit
      di = diff

git 指令與縮寫後的指令比較

git status   = git st
git checkout = git co
git branch   = git br
git rebase   = git up
git commit   = git ci
git diff     = git di

git 指令(以下都用縮寫)

  1. Status

    git st
    
  2. Branch

    # 顯示目前 local git 的 branch
    git br
    
    # 顯示所有 branch (包含 remote branch))
    git br -a
    
  3. Add

    # add single file
    git add <file_path>
    
    # add all unstage file
    git add .
    
    # 強制新增 ignore file in git
    git add -f [file_path]
    
  4. Commit

    git ci -m "content"
    git ci --amend -c {commit hash}
    
  5. Checkout

    # 切換到任何一個 branch 或是任何一點 commit hash 上
    git co <branch_name>
    git co <commit_hash_number>
    
    # 在現在的 branch 上面新開一個 branch 
    git co -b <new_branch_name>
    
    # checkout 一個 remote branch 
    git co -b <local_branch_name> --track origin/<remote_branch_name>
    EX: git co -b feature/123 --track origin/feature/123
    
    # 清除所有 unstage 檔案到上一次的 commit
    git co -- .
    
  6. Diff

    # 查看目前所有 git 的更動內容
    git diff
    
    # 查看某個檔案的變動
    git diff <file_path>
    
    # 查看 git 更動內容並且忽略空白
    git diff --ignore-all-space
    
  7. Merge

    # 一般直接 merge (ex: feature/123 merge to develop)
    # 建議先 pull 在 merge
    git co develop
    git merge feature/123
    
    # 保留 feature branch 上的線
    # 建議先 pull 在 merge
    git co develop
    git merge --no-ff feature/123
    
  8. Pull

    git pull or git pull origin <branch_name>
    
  9. Push

    # 一般的 push 方法
    git push or git push origin <branch_name>
    
    # 與 tag 一起 push
    git push --follow-tags or git push --follow-tags origin <branch_name>
    
    # Delete remote git branch
    git push origin --delete [branch_name]
    
  10. Fetch

    # 同步目前遠端 git 的狀態
    git fetch origin
    
  11. Tag

    # 顯示目前的 tag 狀態
    git tag
    
    # 在某個 commit hash 上面加上 tag
    git tag -a <tag_name> -m "<tag_content>" <commit_hash>
    EX: git tag -a v1.1.0 -m "test1" a9bf65b
    
    # 查詢 tag 的詳細資料
    git show <tag_name>
    EX: git show v1.1.0
    
  12. Reset

    # reset all include unstage
    git reset -q --hard HEAD --
    
    # hard reset 到某次 commit
    ps. 小心使用,中間的所有 commit 都會消失,必須透過 git reflog 去還原之前的 commit
    git reset --hard <commit_hash>
    
  13. Rebase

    # 針對某個 branch 進行 rebase
    git rebase <branch name>
    
    # 針對某個 commit 之後進行 rebase
    git rebase -i <commit hash>
    
    # 針對 root 進行 rebase
    git rebase -i --root
    
  14. Git Flow

    • 認識 git flow: ihower - Git flow 開發流程
    • 安裝 git flow on mac: git-flow cheatsheet
    • 簡單介紹 git flow 種類
      • feature
        • 從 develop 分支出去,常用於開發新的功能,開發完成後就會 merge 回 develop 上
      • hotfix
        • 從 master 分支出去,常用於 stable 版的緊急修復,修復完成後會 merge 回 master 跟 develop 上
      • release
        • 從 develop 分支出去,用於開發版本要釋出成 stable 版,釋出完畢會 merge 到 master 跟 develop 上
    初始化 git flow

    git flow init

    使用 git flow feature 流程

    git flow feature start 123 // 從 develop 建立一個 feature branch 123 出來
    git flow feature publish 123 // 將 feature/123 這個 branch push 到 remote git repo 上
    git flow feature finish 123 // 將 feature/123 這個 feature branch 結束後 merge 回 develop 上,並且會將這個 feature branch 移除

    使用 git flow release 流程

    git flow release start v1.1.0 // 從 develop 建立一個 release branch v1.1.0
    git flow feature publish v1.1.0 // 將 release/v1.1.0 這個 branch push 到 remote git repo 上
    git flow feature finish v1.1.0 // 將 release/v1.1.0 這個 release branch 結束後 merge 進 master 與 develop 上並且壓上版本號,然後將這個 release branch 移除

    使用 git flow hotfix 流程

    git flow hotfix start v1.1.0 // 從 master 建立一個 hotfix branch v1.1.0
    git flow hotfix finish v1.1.0 // 將 hotfix/v1.1.0 這個 branch 結束後 merge 回 master 與 develop 上並且壓上版本號,然後將這個 hotfix branch 移除

使用 Mac 安裝 gitbook server

| Comments

安裝 node.js

先到 node js 的官方網站依照自己的 OS 下載 node js 安裝檔

https://nodejs.org/en/

確認 node js 是否安裝

node -v    
npm -v

安裝 gitbook cli

npm install -g gitbook-cli

開啟本機 gitbook 專案

cd [gitbook folder]
# 跳至 gitbook 目錄

gitbook install
# 安裝 gitbook 相關套件

gitbook serve
# 啟動 gitbook server ,預設為 4000 port

CURL 與 Shell Script 相關使用

| Comments

分享一下最近使用 curl 去 access 網站會需要用到的指令

常用語法

1. 使用 curl 直接 access 網站

curl http://xxx.xxx.xxx

2. 透過 curl post data 給網站

curl --data "Account=xxx&Password=xxx" http://xxx.xxx.xxx
// 在這個範例中傳送了 Account 跟 Password 兩個參數

3. 透過 curl 使用 user agent

curl -A "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36" http://xxx.xxx.xxx
// 此範例為使用 MAC 的 OS 然後還有使用 google chrome 的瀏覽器

4. 透過 curl 去記錄目前所使用的 cookie

1. 取得第一次驗證的 cookie

curl --cookie cookie_file.txt --cookie-jar cookie_file.txt --data "Account=xxx&Password=xxx" http://xxx.xxx.xxx/check.php

// 將驗證資料傳到 check.php 獲得 cookie ,並且將 cookie 存在同層目錄下面的 cookie_file.txt 中

2. 使用已經取得的 cookie file 進行其他的使用

curl --cookie cookie_file.txt http://xxx.xxx.xxx/something.php

shell script 額外使用

1. 使用額外的 config file

  • vim env.conf

    test1="test1"
    test2 = "test2"
    # 宣告會使用到的參數
    
  • vim sourcecode.sh

    source env.conf
    
    # 只要在 source code 中引入這個檔案就可以使用了
    
    echo $test1 # test1
    echo $test2 # test2
    

2. 取得當前執行的目錄

WORKDIR=$(cd "$(dirname "$0")"; pwd)

3. 在 mac 中可以直接雙擊 sh 檔

直接將檔名從 .sh 改成 .command

目前遇到的問題

1. 要傳送兩次 post data 給 check.php 後的 cookie_file 才可以使用

curl --cookie cookie_file.txt --cookie-jar cookie_file.txt --data "Account=xxx&Password=xxx" http://xxx.xxx.xxx/check.php
curl --cookie cookie_file.txt http://xxx.xxx.xxx/something.php

// 這樣會無法在 something.php 中取得到資料

curl --cookie cookie_file.txt --cookie-jar cookie_file.txt --data "Account=xxx&Password=xxx" http://xxx.xxx.xxx/check.php
curl --cookie cookie_file.txt --cookie-jar cookie_file.txt --data "Account=xxx&Password=xxx" http://xxx.xxx.xxx/check.php
curl --cookie cookie_file.txt http://xxx.xxx.xxx/something.php

// 這樣就可以在 something.php 中取得資料

Reference

  1. Linux - shell script 取得當前路徑
  2. 如何雙擊 shell script file
  3. 如何使用 applescript 去呼叫 shell script
  4. 如何使用 curl 進行 session 驗證