2023年7月26日 星期三

從測試角度看FHIR SDK

近期自行開發了一套FHIR SDK。因是自用不對外,也沒有想著要如何寫使用手冊。雖然整個SDK系統內容還算複雜,但從使用角度似乎沒甚麼好說的。

想要深入研究FHIR,真的從無到有開發一次SDK的方式,就能夠知道所有問題所在。

若要直接從SDK設計思維與程式設計的角度切入,那還真的不知要從何說起。經過一番思考後,何不從測試SDK的思維切入,從測試想法來展開FHIR SDK也許是個好主意。

要如何測試Resource

使用者可能會有三種情境:

  •  收到某個Resource TypeJSON檔案。不管你是使用甚麼樣的JSON程式庫,最終一定可以變成字串(string)
  • 有個很好的物件定義結構,協助我們產生符合FHIR規範的JSON字串。
  • 更新修正JSON內容。

潛在問題

雖然不同ResourceJSON內容不同,但所有測試需求都是一致的。

另外一個就是測試版本問題。FHIR不斷地發展,所以,應該要降低改版時,又得重新設計一次的問題。Resource實在太多了,不可能一改版,就重新寫一次(這邊留個伏筆,相對設計SDK也有同樣問題)。

 解決方法

測試系統結構上會有一個抽象父類別讓個別的Resource來繼承,然後把固定的測試函數,寫在這個父類別上。這部分不受FHIR 改版之影響。

而個別Resource類別,主要就是定義JSON字串、建立Resource物件與更新內容。若FHIR有改版時,那就替換JSON字串。新建Resource部分也有可能需要修改,不過測試主要對象是必要欄位。

程式解說-抽象父類別


行號

說明

1

宣告使用FHIR SDK的基礎套件。

所有Resource都會繼承於DomainResource

2

宣告使用System.Text.Json.Nodes套件。

這個是微軟官方提供處理JSON的套件。請參考System.Text.Json.Nodes Namespace | Microsoft Learn

4

命名空間

6

宣告抽象類別。採用泛型,得知目前所有處理的Resource Type

所有的Resource Type都會繼承於DomainResource

8

宣告 T Resource_TargetObject是用新增物件方式所產生的。

9

宣告 T Resource_TargetString是從字串解析取得的。

10

宣告 T Resource_TargetNode是從JsonNode解析取得的。

11

建構元。輸入Resource TypeJSON字串。

13

指派_TargetObject。呼叫設定物件之函數。SetupObject函數由個別Resource測試類別去編寫內容。

14

指派_TargetString。使用泛型技術,呼叫T Resource類別能接受字串的建構元。

15

指派_TargetNode。使用泛型技術,呼叫T Resource類別能接受JsonNode的建構元。

JsonObject.Parse(jsonString)是將字串解析成JsonNode

注意,實務上我們收到的一定是JSON Object,不會是JSON Array。多筆的一定是Bundle Resource,他是JSON Object

17

宣告一個SetupObject 抽象方法,讓繼承者實做。

這是用來產生一個新的 T Resource

18

宣告一個ChangeDataTest抽象方法,讓繼承者實做。

這是一個測試方法,用來測試更新Resource內容時。

20

-

27

測試方法 ResourceNameTest

這是確認 T ResourceJSON Resource字串所宣告的Resource Type是否一致。

28

-

33

測試方法FromJsonNodeTest

這是確認是否能順利透過JsonNode的方式,來建構T Resource

並且利用T ResourceToJsonString,顯示解析後之結果。

34

-

39

測試方法FromObjectTest

這是確認是否能順利透過設定物件內容的方式,來建構T Resource

並且利用T ResourceToJsonString,顯示解析後之結果。

40

-

45

測試方法FromStringTest

這是確認是否能順利透過解析JSON 字串的方式,來建構T Resource

並且利用T ResourceToJsonString,顯示解析後之結果。

程式解說-Resource測試類別(Account 為例)


行號

說明

1

宣告使用到FHIR SDK Complex的資料型態。

2

宣告使用到FHIR SDK Primitive的資料型態。

3

宣告使用到FHIR SDK Account Resource Type

4

宣告使用到FHIR SDK 用於BindValue Set

6

命名空間

8

宣告這是測試類別。

9

宣告測試類別,繼承於ResourceTypeTester,用來測試Account Resource Type

11

宣告_jsonString其內容為Resource TypeJSON 字串。

可從FHIR官方文件中取得。

66

建構元。丟Resource TypeJSON字串給父類別處理。

67

複寫父類別之SetupObject函數。

69

目標回傳一個新的Account物件。

71

設定有Id欄位。資料型態是Id,屬Primitive

FHIR SDK有針對string寫了擴增方法來轉換成FHIR的資料型態。

為了避免與程式語言的資料型態相衝突,FHIRPrimitive資料型態,前面都加上FHIR



72

-

76

設定Text欄位。資料型態是Narrative,屬Complex

因為是Complex所以,是採用新增物件的方式處理。

其中Status的部分,因為有BindNarrativeStatus,所以可以取值。


Div雖然資料型態是XHtml,但可透過字串方式轉換。

77

-

84

設定Identifier欄位,資料型態是Identifier,屬Complex,多筆。

利用C#起始建構元特性來新增物件。

SystemValue都是從字串轉成對應之FHIR Data Type

85

設定Status欄位。資料型態是Code

BindAccountStatus

86

設定Name欄位。資料型態是String

90

宣告ChangeDataTest是測試方法。

91

複寫父類別的抽象方法。

93

-

105

JSON字串產生Resource

隨即進行欄位更新。

Name欄位,也可以使用new 物件的方式來建構。

Subject欄位其資料型態是Reference,且為多筆。

106

測試是否可以正常產生物件。

107

使用FHIR SDK ResourceToJsonString方法,倒出資料。

測試結果

測試前


測試後






 

2 則留言:

  1. Hi! Are you using the Firely .NET SDK for this? https://github.com/FirelyTeam/firely-net-sdk

    If not, it would be really worthwhile to check it out and reuse.

    回覆刪除
  2. Thank your suggestion. I used it before. But I aim to understand the FHIR fully by developing the SDK myself.

    回覆刪除