Daily Grind

システム開発関連の忘備録です

テスト観点

個人的なメモです。

テスト観点としては、以下は抑えとく。


・OS種別
・ブラウザ種別
・ディスプレイサイズ、フォント、フォントサイズ
・入力値(文字列や配列が空やnull書式)
閾値(最大、最小、異常値、境界値)※桁数、文字列長、数値
・最大長文字列での表示
・文字列のエスケープ処理(CSV、URL...)
・タブオーダー
・優先度(画面の優先度、処理の優先度...)
・検索条件の一致、不一致(完全一致、前方一致...)
・メッセージ、ログ出力
・画面遷移
文字コード
・ボタン連打
・DB異常(タイムアウト、デットロック)
・Webサーバ異常
・競合(他機能との)
・多重起動
・通信速度(帯域)
・高負荷
・多言語(表示、領域に収まるか、非互換はないか)
・前版と互換性の確認(ソート順が変わって非互換になったり)
・多数台環境
・長期間稼動(プロセスのメモリ増加、CPU増加、差分をチェック)
・ファイルエラー、競合
・ネットワーク切断、復旧
・リトライ処理(エラー発生後に正常動作するか等)
・その他エラー系、異常系
・ユーザ権限
・下位互換

gettextによる多言語化

目次
1.gettextによる多言語化の基本的な処理手順
2.サンプル
3.懸念事項



1.gettextによる多言語化の基本的な処理手順
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄

(1) ソースコードに、"xgettext"で検出する為のマクロ定義を埋め込む。
  setlocale()など必要な前処理やヘッダファイルインクルードを組み込む。
(2) xgettextでメッセージを抽出し、翻訳のためのテンプレートファイル(.potファイル)を作成
(3) テンプレートファイルを基に各言語に翻訳し、テンプレートカタログ(.poファイル)を作成
(4) メッセージカタログをバイナリファイル(.moファイル)に変換する
(5) 作成したバイナリファイルをロケールディレクトリに置く。


2.サンプル
 ̄ ̄ ̄ ̄ ̄ ̄
以下のソースを多言語化してみる。

 【test.c】

#include <stdio.h>                     
                                       
char *msg = "GNU gettext excersize";   
                                       
int main() {                           
    puts("Hello, World!");             
    puts(msg);                         
    return 0;                          
}                                      

(1) ソースコードに、"xgettext"で検出する為のマクロ定義を埋め込む。
  setlocale()など必要な前処理やヘッダファイルインクルードを組み込む。

 【test.c】

#include <stdio.h>                                                                      
                                                                                        
/* setlocale() */                                                                       
#include <locale.h>                                                                     
                                                                                        
/* bindtextdomain(), textdomain() */                                                    
#include <libintl.h>                                                                    
                                                                                        
#define _(String) gettext(String)                                                       
#define N_(String) gettext_noop(String)                                                 
#define gettext_noop(String) (String)                                                   
                                                                                        
char *msg = N_("練習サンプル");                                                         
                                                                                        
int main() {                                                                            
    /* ロカール名を環境変数から取得 */                                                  
    setlocale(LC_ALL, "");                                                              
    /* ドメイン名"test"のメッセージカタログディレクトリをカレントディレクトリに設定 */  
    bindtextdomain("test", ".");                                                        
    /* ドメイン名を"test"に設定 */                                                      
    textdomain("test");                                                                 
	                                                                                     
    puts(_("こんにちは、世界!"));                                                      
    puts(_(msg));                                                                       
    return 0;                                                                           
}                                                                                       

コンパイル

	$ gcc -Wall -o test test.c   
	$ ./test                     

(2) xgettextでメッセージを抽出し、、翻訳のためのテンプレートファイル(.potファイル)を作成する

	$ xgettext -k"_" -k"N_" -o test.pot test.c --from-code=UTF-8  
	$ ./test                                                      

  ※キーワードに"_", "N_"の二種類を指定することで、両方のマクロが適用された翻訳対象文字列を抽出できる。

(3) テンプレートファイルを基に各言語に翻訳し、テンプレートカタログ(.poファイル)を作成する

$ cp test.pot en.po

  en.poを編集して英訳する。

 【en.po】

	"Content-Type: text/plain; charset=UTF-8\n"   ※今回のサンプルではUTF-8を指定した。
	...                                           
	#: test.c:13                                  
	msgid "練習サンプル"                          
	msgstr "GNU gettext excersize"                
	                                              
	#: test.c:23                                  
	msgid "こんにちは、世界!"                    
	msgstr "Hello, World!"                        


(4) メッセージカタログをバイナリファイル(.moファイル)に変換する

	$ msgfmt -o test.mo en.po           

(5) 作成したバイナリファイルをロケールディレクトリに置く。

	$ mkdir -p ja/LC_MESSAGES             
    $ cp test.mo en/LC_MESSAGES/test.mo   

(6) 動作確認

	$ LANG=C ./test                       
	こんにちは、世界!                    
	練習サンプル                          
	                                      
	$ LANG=en_US.UTF-8 ./test             
	Hello, World!                         
	GNU gettext excersize                 


3.懸念事項
 ̄ ̄ ̄ ̄ ̄ ̄
(1) LANG=Cの場合の表示。

 「LANG=C」では、動作的にはmsgidがそのまま出力されます。
 今回は、_("日本語")のメッセージカタログを持つことになるので
 「LANG=C」だと日本語リテラルで出力されます.

(2) ソースの文字コード

 ソースファイルの文字コードは統一しておく必要があります。
 既存ソースの文字コードが統一されていない場合は文字コードの変更が必要です。

Gitで特定のバージョンのソースを取得


■特定のバージョンのソースを取得する方法
 あるbranchの最新版でなく、以前のバージョンのソースを取得する方法です。
 ※ローカルに最新のクローンがある状態前提です。

 ①右クリックのメニューの TortoiseGIT>切り替え> [...]をクリック
 ②対象ブランチを右クリック > ログを表示
 ③対象のコミットログを右クリック > ここへ切り替え
 ④「新しいブランチを作成」のチェックは外して、OKボタンを押下。

 単純にログ画面を表示して③からの操作をするだけでもOKです。

 

SSHポート転送

SSHポート転送でリモートデスクトップしたいときの手順です。


経路
 ローカルPC⇒踏み台⇒作業したいPC


1.TeraTermを開く

2.新しい接続で踏み台サーバへログイン

3.TeraTerm-設定-SSH転送を開く

4.SSH転送の設定を追加する。

  ローカルのポート:10022(これでなくてもよい)
  リモート側ホスト:作業したい対象(リモデ先)
           (例えばは153.156.XXX.XXX)
  リモート側ポート:3389(リモートデスクトップのポート)

5.リモートデスクトップを起動する

6.ログインする

  localhost:10022 user/pass
  ※10022は、SSH転送設定時のローカルのポート。

優れたUIデザインを作るために知るべき12のTips

============================================
優れたUIデザインを作るために知るべき12のTips
============================================

1.先進的な技術を使う理由
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
 どんなUX(ユーザーエクスペリエンス)をユーザーに与えたいですか?

2.実際の使われ方(ユースケース)を想定しながらデザインする
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
 実際にそのWebサイトやアプリが実際に使われるシーンを想定

3.ユーザーを明確にカテゴライズする
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
 あなたが議論したいユースケースに一人づつペルソナを割り振って考えてみてください
 一つUIを作るために二つのUIを作り、比較してみてください。

4.ユーザーフローを考える
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
 ユーザーエクスペリエンスを考えるためには、アプリケーションフローを考えることが重要

5.プロトタイプについて
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
 UIデザインはまずプロトタイプから作ります。

6.次のステップを明確にする
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄

7.見えるものの数を減らす
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
 これには3つの段階があります。
 ・感情的段階 脳が画面上の色、レイアウト、画像を認識する
 ・解析段階  脳が画面上のすべての要素の目的を考える
 ・実行段階  ユーザーが最初のUI要素とやりとりを始める

8.一貫性を持たせる
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
 使用するUIに一貫性を持たせる必要があります

9.ページ遷移させない
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
 あなたがバックエンドを担当している場合、完全なページ遷移を避けてください。
 代わりにAJAXを使い、新しい要素や情報をロードしてください。

10.トランジションを使って状態を変更する
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
 あなたがアプリケーションの一部の状態を変更した時、何が起こったのかをユーザーにちゃんと
 伝えるためにシンプルなトランジションを使用することができます。
 例えば、何かを非表示にしたい時、それをフェードアウトさせ、
 ユーザー前の画面に戻りたい時、どこを見ればいいかわかるような状態です。

11.繰り返して絞り込み
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄
 UIデザインのプロセスは反復的です。

12.あなたのユーザーにすばらしい体験を与える
 ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄

Webrickでダイジェスト認証

#!/usr/bin/ruby

# -*- coding: utf-8 -*-

IP       = '127.0.0.1'             #IPは変えること
PORT     = '4000'                #port は1024以下にしないこと、する場合はroot権限
DOC      =  './'
#CGI_PATH = '/usr/local/bin/ruby' #環境にあわせてwindows  'C:\Ruby193\bin\ruby.exe'
CGI_PATH = '/usr/bin/ruby'

require 'webrick'

opts  = {
  :BindAddress    => IP,
  :Port           => PORT,
  :DocumentRoot   => DOC,
  :CGIInterpreter => CGI_PATH
}

srv = WEBrick::HTTPServer.new(opts)

# ダイジェスト認証の設定(引数にはダイジェスト認証用のデータベースのパスを渡す)
pswd = WEBrick::HTTPAuth::Htdigest.new("dot.digest")

#if pswd.get_passwd("Secret Zone", "admin", false) == nil
#  pswd.set_passwd("Secret Zone", "admin", "sysadmin") # realm, user, passwd
#  pswd.flush                                     # ファイルに書き込む
#end

auth = WEBrick::HTTPAuth::DigestAuth.new(:UserDB => pswd, :Realm => "Secret Zone")

# HTTPServerの/loginにダイジェスト認証を設定
srv.mount_proc("/"){|req, res|
  # 認証
  auth.authenticate(req, res)
  res.body = "<html><head><title>うんこおお</title></head><body><p>OK.</p></body></html>" 
}

# view.cgiにhttpアクセスした場合、view.rbをcgiで動かす
#srv.mount('/view.cgi', WEBrick::HTTPServlet::CGIHandler,  'view.rb')

#コマンドラインでCtrl+Cした場合止めるイベントハンドラ
Signal.trap(:INT){ srv.shutdown}

#サーバースタート
srv.start