質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

91.36%

  • C#

    4756questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • WPF

    517questions

    Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

DataTableの中身をAssertで比較する方法

解決済

回答 1

投稿 2017/12/05 09:40 ・編集 2017/12/05 10:36

  • 評価
  • クリップ 0
  • VIEW 94

---t---

score 25

表題の件で質問させてください
開発環境はVS2015です
使用言語はC#です

現在DataTable(CBtest.Combotb)を単体テストで比較しようとしています
テストで確認したいCBtest.CombotbはSQLでデータを取ってきているのですがデータ数がとても少ないためテストデータは自分で記入しました

CBtest.Combotbには
テストコードに記入した以下と同じデータが入っています


"name"


"AAA"
"BBB"
"CCC"
"DDD"
"EEE"
"FFF"

今回のテストでは上記データと合致するか確認したいです

以下のコードでTableTestにもCBtest.Combotbにも同じデータは入っているのですが、テストを実行すると”Assert.AreEqual に失敗しました。<> が必要ですが、<> が指定されました。”というエラーが出ます

この場合何が間違ってるのでしょうか

また、今回はデータ数が非常に少なかったのでテストすべきものは明確ですが、何万とあるデータを保持しているDataTableのテストはどのような観点でテストすべきでしょうか

重ねて申し訳ありませんがよろしくお願いいたします

以下のコードはテストメソッドです

 [TestMethod()]
        public void combodataGetTest1()
        {
            var TableTest = new DataTable();
            TableTest.Columns.Add("name");
            TableTest.Rows.Add("AAA");
            TableTest.Rows.Add("BBB");
            TableTest.Rows.Add("CCC");
            TableTest.Rows.Add("DDD");
            TableTest.Rows.Add("EEE");
            TableTest.Rows.Add("FFF");



           CBtest.combodataGet();
           Assert.AreEqual(TableTest, CBtest.Combotb);
        }
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • SurferOnWww

    2017/12/05 10:05

    まず定義不明な変数、メソッドがないようにしてください。それから、あなたの開発環境を書いてください。加えて何がどのように一致するとイコールと判断するのかの定義を明確にしてください。

    キャンセル

  • ---t---

    2017/12/05 10:37

    ご指摘ありがとうございます。修正させていただきました

    キャンセル

回答 1

checkベストアンサー

+1

依然として CBtest.Combotb とか定義不明ですが、要するに 2 つの異なるインスタンスの DataTable の中身が同じかどうか調べたいということと理解してレスします。

検証などはしておらずググって調べた限りですが、質問者さんのコード、

Assert.AreEqual(TableTest, CBtest.Combotb);

は Assert.AreEqual メソッドの多々あるオーバーロードの内、Assert.AreEqual メソッド (Object, Object) を呼び出しているはずです。

その場合、参照の等価を調べることになり、2 つの DataTable のインスタンスが異なればアサーションは失敗するはずです。詳しくは以下の記事を見てください。

Assert.AreEqual method usage in checking DataTable types
https://stackoverflow.com/questions/18365915/assert-areequal-method-usage-in-checking-datatable-types

何にせよ、Assert.AreEqual メソッドでは、DataTable の中身が同じかどうか調べるのは無理です。

Assert クラスの他に、コレクションを扱う CollectionAssert クラスがありそれにも AreEqual メソッドが実装されています。詳しくは以下の記事を見てください。

C#でのテスト
https://so-zou.jp/software/tech/programming/c-sharp/test/

ただし、それも ICollection を継承したコレクション同士を比較するものであり、DataTable を直接比較することはできなそうです。

CollectionAssert.AreEqual を使うなら DataTable を何らかの方法で ICollection を継承したオブジェクトに変換し、それを比較することになりそうです。

なお、本題とはちょっと違う話ですが、同じがどうか調べると言っても、「値の等価」を調べるのか「参照の等価」を調べるのかで話が違ってきますのでご注意ください。「値の等価」「参照の等価」について、詳しくは以下の記事を見てください。

2つの値が等しいか調べる、等値演算子(==)とEqualsメソッドの違い
http://dobon.net/vb/dotnet/beginner/equality.html

投稿 2017/12/05 11:52

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/12/06 14:31

    回答ありがとうございます
    CBtest.Combotb はテスト対象クラスcomboboxdataのインスタンスとそのクラスでデータを加工したデータテーブルCombotb(今回のテスト対象物)になります。
    アドバイスをもとに以下のコードを作成いたしました
    今回は中身の順番や内容の確認なのでString型で受けて比較するようにしてみました

    [TestMethod()]
    public void combodataGetTest1()
    {
    var TableTest = new DataTable();
    TableTest.Columns.Add("line_name");
    TableTest.Rows.Add("全サブライン");
    TableTest.Rows.Add("DTライン");
    TableTest.Rows.Add("Cライン");
    TableTest.Rows.Add("DCライン");
    TableTest.Rows.Add("Mライン");
    TableTest.Rows.Add("Kライン");


    CBtest.combodataGet();

    string tableCk;
    string testData;


    for (int a = 0; a < TableTest.Columns.Count; a++)
    {
    for (int b = 0; b < TableTest.Rows.Count; b++)
    {

    tableCk = TableTest.Rows[b][a].ToString();
    testData = CBtest.Combotb.Rows[b][a].ToString();

    Assert.AreEqual(tableCk, testData);

    }
    }
    }

    キャンセル

  • 2017/12/06 16:23

    実際には DataTable には複数の列が含まれ、string 型以外にも int, bool, decimal, DateTime 等々のデータもあるのではないですか? もしそうであれば、他の方法を考えた方がよさそうな気がします。例えば CollectionAssert.AreEqual メソッド (ICollection, ICollection, IComparer) が使えないか検討するとか。

    キャンセル

  • 2017/12/06 16:40

    ありがとうございます
    確かに今回テストしたかったのはString型だけだったので上記のやり方でよかったですが他のクラスでは仰る通り様々な型が使われているのでCollectionAssertなどを検討してうまくいけば置き換えていこうと考えます

    キャンセル

  • 2017/12/06 18:21

    余計なお世話かもしれませんが・・・

    > 確かに今回テストしたかったのはString型だけだったので上記のやり方でよかったですが

    たとえ「今回テスト」のケースに限っても、DataTable の(または DB から直接)line_name 列の各文字列を List<string> 型オブジェクトとして取得し、それを CollectionAssert.AreEqual メソッド (ICollection, ICollection) に渡すといった方法の方がコードがスマートかつ美しいと思うのですが、いかがですか?

    まぁ、見栄えの違い・個人的な好みの問題だけで、結局は中ではループで回して処置しているでしょうから、性能上はあまり差はないのかもしれませんが・・・

    キャンセル

  • 2017/12/06 23:29

    ありがとうございます
    基礎知識等もまともに勉強してない浅い状態で触れているので勉強になります。
    ありがとうございます。

    自分自身Listは全然使ったことがないのでこれを機に勉強してみます
    また、重ねて申し訳ないのですが、DataTableの扱いに関してお聞きしたいのですが、DataTableを加工したり中身を抽出するのはループを回すのが一般的な理解なのでしょうか?どのサンプルを見てもループを使う記述が多いのでよく分からないまま使っているのですが、データ量が多いから繰り返しをつかうのでしょうか?
    変な質問で申し訳ありません。

    キャンセル

  • 2017/12/07 00:28

    > DataTableを加工したり中身を抽出するのはループを回すのが一般的な理解なのでしょうか?どのサンプルを見てもループを使う記述が多いのでよく分からないまま使っているのですが、データ量が多いから繰り返しをつかうのでしょうか?

    サンプルというのは何を見てるのか知りませんが、少なくとも自分が知る限り一般的なんてことはないはずです。そうせざるを得ないからそうしているだけでしょう。

    例えば、Visual Studio のデータソース構成ウィザードを利用して型付 DataSet + TableAdapter を作って、それを利用してアプリを作ると、以下のページの図のような構造のアプリが、ほとんど自分でコードを書くこと無しに作れます。

    Windows フォーム アプリケーションでのデータへの接続
    https://msdn.microsoft.com/ja-jp/library/wxt2cwcc(v=vs.120).aspx

    そこに、プログラマがコードを書いて DataSet / DataTable の中のデータをループを回して取得するなんてことはありません。

    「基礎知識等もまともに勉強してない」とのことですが、それではなかなか話が通じにくいです。本を読むなどして体系的な知識を身に着けてください。

    キャンセル

  • 2017/12/08 13:34

    DataSet / DataTable について、自分的に理解しやすかった記事を紹介します。以下の記事の図1と図2を見てください。

    DB 設計者のための明解 ADO.NET 第 1 回
    https://msdn.microsoft.com/ja-jp/library/cc482903.aspx

    上で紹介した記事「Windows フォーム アプリケーションでのデータへの接続」でデータベースの編集・更新操作がどのように実現されているかはその図を見ると一目瞭然です。

    そもそも、DataSet / DataTable はそのような目的で使うものということで、質問者さんの目的に合っているかどうか検討してみることをお勧めします。

    また、「同じ」ということについても、どこまで同じであるべきかを、その図を見て考えてみることをお勧めします。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

ただいまの回答率

91.36%

関連した質問

同じタグがついた質問を見る

  • C#

    4756questions

    C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

  • WPF

    517questions

    Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです