開発サイドから見るバグ報告の話

こんにちは株式会社イメージ・マジックのsoenoです。

私はフロントエンド側でバグを受け取る側にいます。
いざバグが上がってくると手一杯になり伝えられない報告について。
もらうと助かる報告とその理由などについて書いてみようかと思います。

まず不具合の発生時に報告を上げる側は以下のような思いを抱いているのではないかと思います。
・壊れているので直してほしい。
・クレーム来てるから早く動いてほしい。
・細かいことはわからないけどとにかく何とかして。

急いでほしい、早く結論が知りたい。
そんなときほど初期に上がる報告が重要です。
開発側で報告を受けたとき、いろいろと調べるポイントがあります。
素敵な報告をいただくと調べなくてはいけない箇所が減ったり、
うっすらと見当がついたり、もしくは重点的に確認するべき場所を決定できます。

ではもらってうれしい報告を手軽に書く方法について考えてみます。
あってほしい情報や、必要な項目について抜けなく上げるために
作文などでなじみのある5w1hに照らし合わせて考えました。
5w: いつ、どこで、だれが、何を、どうした。
1h: どのように

報告時に書く5w1hを言うと以下のようになります。

・いつ(When)
内容:バグ発生時刻(特にサーバー周りのバグの時に重要)
理由:記録を確認するときに膨大な情報の中から探す場合、時刻がわからないと探しきれないことがあります。

・どこで(Where)
内容:ネットワーク接続環境など。社内で接続しているかそれとも社外か。遅い回線ではないか。
理由:ネット回線のスピードによる挙動の場合そのスピードでないと再現しないことがあります。
対処する場所、対処可能な部署が違うこともあり得ます。

・だれが(Who)
内容:バグ発生時の環境、ブラウザ、ブラウザバージョン、端末(pc?smartphone?)、OS(windows?mac?linux?…)
理由:特定のブラウザのみで発生する動きがあるので、そのブラウザしか再現しないことがあります。

・なにを(What)
内容:ウェブでいうとどのページの(url等)どの要素に対して操作を行っていたか
理由:ページとどの要素かがはっきりしていると違うページの違う要素を延々調べなくて済むようになります。

・なぜ(Why)
内容:そもそも何のためにその操作をしたか。
理由:操作の意図ですが、想定した操作外での不具合の把握でしょうか。
バグ取りというよりはサイト改修、改善時に知っておきたいところです。

・どのように(How)
内容:バグ発生のための手順
理由:手元の環境で再現するかどうかはとても重要です。壊れていないものを直すためには
どうしたら壊れるのか、どこが壊れるかもしれないのかなど、上の5W総出で類推することになります。
特徴的な動作や、何か心当たりやひらめきがないと難しいということもあります。

追加でもう一つ5w1hでは足りなかった要素として”hope”を足します。

(英語的に正しいかの検証はしません。)

・どうなってほしかったか(Hope)
内容:正しく動いていたらどうなるか
理由:バグと仕様との判断と、一見正しく動いているように見える挙動の際に何が問題になっているかを特定します。

何か特殊な状態があればそれも追記してあるとなおいいです。
例として思いつくものを上げると
・同一画面を複数ブラウザで開いていた。
・ブラウザで戻るボタンを押してのフォーム入力。
等々

この報告を私が読む場合、下に書いた順番になります。
0、特殊な操作、状態の報告
1、どのように(How)
2、どうなってほしかったか(Hope)
3、なにを(What)
4、だれが(Who)
5、いつ(When)
6、どこで(Where)

順番は個人の手法、サーバー担当かフロント担当かで違ってくると思います。
特に抜けて困るのは1、2、3番。
サーバー側は加えて5番。(多分)

早く回答してほしい、今すぐ着手してほしい。
そういうときほど初期の報告が大切です。
そんなこと言ってもちゃんと書いても遅いじゃん。
という意見もあるかと思います。
ですが、ちゃんと書いていなければきっともっと遅かったはず!
というわけでもらってうれしい報告について書きました。

最後に、こちらの記事は一個人としての意見ですのでご注意ください。
フロント周りやってますのでサーバーあたりに抜けがあるのではないかと思います。
開発にもいろいろあります。自分のケースによりあうものを参考にするといいと思います。
(web上に既にきれいに書かれているものもあります。)

初心者がなやむ型の概念@2018/05/28

はじめに

こんばんわ!
今回担当の廣田です。

未経験入社で早3カ月たちました。
日々の業務のなかで得た知識などを書いていこうと思います。
高度な内容は書けませんが、同じように未経験からプログラミングを始めようと思ってらっしゃる方と共有できたり、学習の役に立てば良いなとおもいます。

今回は、型について備忘がてら書こうと思います。

phpの型指定

ベテランSEの方々には、当然の概念であろうデータ型。
恥ずかしながら、実業務のコードを見たときに一番初めにつまづいたところでした。

-型とは:整数型(int)や、文字列型(string)のようなデータ(値)の種類の分類のこと。

参考:PHPマニュアル

実業務のコードに出現した型指定はこんな以下のようなものでした。

public function findForListBox(Organization $org):array
{
	return $this->createQueryBuilder('m')
	->andwhere(m.organization = :org)
	->.....
}

メソッド名の後ろに「:(コロン)+ 型」で戻り値の型指定をするんですね。
このコロンが気になりすぎてネットで調べましたが、基礎的すぎるのか
型指定だと説明しているサイトはあまり無かったように思います。

プロジェクトで使っているフレームワーク、symfonyでは
アノテーションで記述したり。

/**
     * @param string $email
     * @param int $exclusiveId
     * @return bool
     */
    public function existsByEmail(string $email, int $exclusiveId): bool
    { ...

型キャスト

そのままだと戻り値が意図した型にならず、エラーが返ってくることがあります。
例えば

public function __toString()
    {
        return $this->getId();
    }

とすると以下のようなエラーがかえってきます。
「Return value of __toString() must be of the type string, integer returned」

先輩に聞いたところ、「キャストした形にして」とのこと。
キャスト?なにそれ楽しそう。ディズ〇ーランドのスタッフのことかしら、とか思ったのは秘密です。

型キャストを行うことで型の変換ができるんですね!

return (string)$this->getId();

とすると、string型に変換して返してくれます。

例:
<?php 
$foo = 10; // $foo はintegerです 
$bar = (boolean) $foo; // $bar はtrue(boolean)です 
?>

参考:PHPマニュアル,型の相互変換

フォームの値をコントローラで$Request->get()するときに凡ミスした点

フォームのチェックボックスがチェックされたらDB登録する機能を作りたかったある日。

html
<form>
	<input type="checkbox" name="isAgree" value="true">はい
	...
	<button type='submit'>保存</button>
</form>
controller

$isAgree = $request->get("isAgree")
if($isAgree){
	 $this->em->persist($user);
     $this->em->commit();
}

エラーになりました。

原因がわからず、しばらく考えこんでしまいましたが
とりあえずvar_dumo($isAgree)。

string(4)"true"

う~ん、値とれてるみたいだけど…
…ん?string?なぜ?

原因はhtml側で「value=”true”」としていたところでした。
bool値を返したいなら「value=true」としなくていけないんですね^^;;
勉強になりました。

まとめ

型について、完全には理解できていませんが、補完やバグ発見のためできるだけ戻り値を指定するべきとのことでした。
型を指定することで大きな問題になる前にエラーを特定できるなど
安全なプログラムを書くために有益なようです。

配列だと思ってたらオブジェクトだったり、
いまだにつまづくことが多い型ですが、よくわからなかったらとりあえずvar_dump()するようにしています。
そうすると該当のメソッドがどういう形で値を返してくるのかというメソッドへの理解や、初学者にはイメージしづらいオブジェクトの構造なんかも理解できたりします。

とりあえずエラーになったらvar_dump、
困ったらvar_dump、
暇になったらvar_dumpしてます。

入社から3カ月、
とりあえずvar_dumpとは友達になれたような気がします。

Vue.js 実務でハマったところ @2018/05/21

はじめに

こんにちは!
株式会社イメージ・マジックの技術ブログ、今回担当の宮川です。

本ブログでは、イメージ・マジックがどんな技術を扱っているのかを知ってもらうために、業務で得た知識のまとめやハマって解決したこと、技術選定理由、最新技術動向などや、社内の雰囲気が伝わる内容を書いていきたいと思います。

今回は、社内のプロジェクトで採用している、Vue.jsについて書きます。

Vue.js所感

Vue.js使い始めて2カ月ですが、所感として良いところは概ね以下かなと思ってます。

  • データバインディングが簡潔
  • 部品化しやすい
  • 機能の分類が細やかで配慮が行き届いている
  • だいたいライフサイクルがいい感じにやってくれる

Vue.js ハマったところ

以下、まとめました。

1. Arrayの更新は、以下の方法で更新しないとVue.jsが検知してくれない

// Vue.set
Vue.set(vm.items, indexOfItem, newValue)

// Array.prototype.splice
vm.items.splice(indexOfItem, 1, newValue)

https://www.elastic.co/jp/products/elasticsearch

2. DOMレンダリングが完了したタイミングで処理したい

Vue.nextTick(function() {
  //処理
})

参考:いつ DOM が更新されますか?

 

3. 親子間のデータの受け渡し

// 親はプロパティを渡す
<children customprop="parent.child"></children>

// 子はcustompropを受け取る
Vue.component('my-component', {
   template: `<input type="text" value="customprop">`
})

 

4. 「input type=”file”」は、値をbindできない


// NG v-modelでbindできない
<input type="file" v-model="property.file"/>

// ファイルを取得する場合は、onChangeでイベントを受け取る
<input type="file" @onChange="storeFile($event)"/>

// js
...
storeFile: function(event) {
   const file = event.target.files[0]
},
...

 

5. $.emit()には、キャメルケースは使用できない

// NG(キャメルケースは不可)
$.emit('updateParent')

// OK(チェインケース(ハイフン区切り)は可。)
$.emit('update-parent')

 

6. Vue.jsのtemplateの最上位タグには v-forは使用不可

// NG
Vue.component('my-component', {
   template: `
<li v-for="item in items">
                {{ item.message }}
              </li>

`

})

// OK
// 最上位タグの子タグで、v-forを使用する。
Vue.component('my-component', {
  template: `
<ul>
               
<li v-for="item in items">
                 {{ item.message }}
               </li>

             </ul>

`
})

 

7. webpackで複数のjsファイルでそれぞれ定義したVueが読み込めない

webpackで分割すると、Vue自体のインスタンスが異なるためイベントが発生できない。importすれば問題無く動作する。

import {EventBus} from '../Util/EventBus';
import AutoCompleteInput from '../AutoCompleteInput.vue';
import AutoCompleteList from '../AutoCompleteList.vue';
...

 

8. Webpackで単一ファイルコンポーネントをcompileすると、cssがjs以下に出力

× public/js/...
○ public/css/...

 

9. Vue.jsの初期化後に、動的に追加したhtmlにVue.jsは適用できない

図のInitでEventsのAttach等行うため