3

C# オブジェクトを JSON にシリアル化し、ネットワーク経由で送信し、JSON を Python オブジェクトに逆シリアル化するコードを書いています。

逆も行われます。つまり、Python オブジェクトを JSON にシリアル化し、それをネットワーク経由で送信し、JSON を C# オブジェクトに逆シリアル化します。

C# 側では、ServiceStack JSON ライブラリを使用します。Python では、組み込みの json ライブラリを使用しています。C# ライブラリは必要に応じて簡単に変更できますが、Python のライブラリはそれほど変更されません。

// C#
var serializer = new JsonSerializer();
var json = serializer.SerializeToString(リクエスト);

// パイソン
// JsonCodec は JSONEncoder から継承し、'default' にフックして、
// obj.__dict__ を返します。ここで、obj はシリアル化されるオブジェクトです
actualSerializedResponse = JsonCodec().encode(応答)

ServiceStack でシリアル化された JSON が Python 側で期待どおりであることを確認するために、C# で単体テストを作成しました。テストでは、Foo のインスタンスが作成され、ハードコードされた値が入力されてからシリアル化されます。妥当性を確認するために、シリアル化された JSON をファイルに保存された JSON と比較します。ファイルの内容は、Python 側が期待するものを表しています。

同様に、組み込みの json ライブラリのシリアル化された JSON が C# 側で期待どおりであることを確認するための Python の単体テストがあります。繰り返しになりますが、妥当性を確認するために、実際のシリアル化された JSON をファイルに保存された JSON と比較します。

どちらの場合も、シリアル化された JSON をファイルに保存された JSON と比較しているという事実は、プロパティが JSON にシリアル化される順序が、テストが実行されるたびに一貫している必要があることを意味します。

私の質問:

  • C# 単体テストでは、JSON 内のプロパティの順序は、インスタンスがシリアル化されている C# クラスでプロパティが定義された順序と一致しているようです。これは当てにできるでしょうか?

  • Python 単体テストでは、プロパティの順序は一貫していますが、任意です。これはdictに依存しており、Python 辞書は順不同であるため、理にかなっています。しかし、これはいつでもどこでも信頼できますか?

  • これをすべて行うより良い方法はありますか?

よろしくお願いします。

4

2 に答える 2

1

最初の 2 つの質問は簡単に解決できます。文書化されていない、実装固有の動作を回避できる場合は常に依存しないでください。ここは避けてもいいと思います。この回答をもう少し具体化するために、最後の質問に時間を割きます。

これをすべて行うより良い方法はありますか?

最初のステップは、現在書いているものが単体テストではないことを認識することです。

具体的には:

次の場合、テストは単体テストではありません。

  • ネットワークを介して通信します
  • ファイルシステムに触れる

あなたのテストはこれらの両方を行っています。テストに価値がないと言っているわけではありませんが、単体テストではないことに注意することが重要です。これらのテストが機能しているレベルは、統合テストです。統合テストは次のとおりです。

個々のソフトウェア モジュールを組み合わせてグループとしてテストする、ソフトウェア テストのフェーズ。単体テストの後、検証テストの前に発生します

あなたの問題は、統合と単体テストのタスクを混在させようとしていることだと思います。

単体テストを作成するときは、各テストが依存するコンポーネントをできるだけ少なくし、可能な限り特定のケースに対処する必要があります。あなたの場合、それは C# と Python の両方でのテストを意味し、どちらも他方からの出力に依存していません。両方のプログラムで、必要な最も単純なケースでシリアライゼーション コードを動作させ、必要な JSON の読み込み/ダンプが得られることを検証します。これは、単体テスト コードで JSON を文字列として手書きすることを意味する場合があります (これが問題にならないように、テストを十分に小さくする必要があります)。

統合テストでは、さまざまな部分が互いに通信するときに何も爆発しないことを確認したいだけです。ここでは、シリアル化と読み取りが正しいことを心配する必要はありません。単体テストで既にカバーしているためです。彼らがうまく話せたら、素晴らしいです!

次に、バグに遭遇した場合は、それらを修正し、適切なテスト ケースで文書化します。最終的には、多数小さな単体テストと、わずかに大きな統合テストがいくつか必要になります。

于 2012-04-05T22:54:42.210 に答える
1

Python 側に関しては、JSON デコーダーに「順序付き辞書」を使用するオプションを渡すことができます (ただし、python 2.7 が必要です)。

http://docs.python.org/library/json.html#json.loadから:

object_pairs_hook は、任意のオブジェクト リテラルをペアの順序付きリストでデコードした結果で呼び出されるオプションの関数です。dict の代わりに object_pairs_hook の戻り値が使用されます。この機能を使用して、キーと値のペアがデコードされる順序に依存するカスタム デコーダーを実装できます (たとえば、collections.OrderedDict() は挿入の順序を記憶します)。object_hook も定義されている場合は、object_pairs_hook が優先されます。

于 2012-04-05T22:54:19.583 に答える