How to use CmpMarshaledBody method of tdhttp Package

Best Go-testdeep code snippet using tdhttp.CmpMarshaledBody

test_api.go

Source:test_api.go Github

copy

Full Screen

...800 ta.dumpResponse()801 }802 return ta803}804// CmpMarshaledBody tests that the last request response body can be805// unmarshaled using unmarshal function and then, that it matches806// expectedBody. expectedBody can be any type unmarshal function can807// handle, or a [td.TestDeep] operator.808//809// See [TestAPI.CmpJSONBody] and [TestAPI.CmpXMLBody] sources for810// examples of use.811//812// It fails if no request has been sent yet.813func (ta *TestAPI) CmpMarshaledBody(unmarshal func([]byte, any) error, expectedBody any) *TestAPI {814 ta.t.Helper()815 return ta.cmpMarshaledBody(false, unmarshal, expectedBody)816}817// CmpBody tests the last request response body against818// expectedBody. expectedBody can be a []byte, a string or a819// [td.TestDeep] operator.820//821// ta := tdhttp.NewTestAPI(t, mux)822//823// ta.Get("/test").824// CmpStatus(http.StatusOK).825// CmpBody("OK!\n")826//827// ta.Get("/test").828// CmpStatus(http.StatusOK).829// CmpBody(td.Contains("OK"))830//831// It fails if no request has been sent yet.832func (ta *TestAPI) CmpBody(expectedBody any) *TestAPI {833 ta.t.Helper()834 if expectedBody == nil {835 return ta.NoBody()836 }837 return ta.cmpMarshaledBody(838 true, // accept empty body839 func(body []byte, target any) error {840 switch target := target.(type) {841 case *string:842 *target = string(body)843 case *[]byte:844 *target = body845 case *any:846 *target = body847 default:848 // cmpMarshaledBody always calls us with target as a pointer849 return fmt.Errorf(850 "CmpBody only accepts expectedBody be a []byte, a string or a TestDeep operator allowing to match these types, but not type %s",851 reflect.TypeOf(target).Elem())852 }853 return nil854 },855 expectedBody)856}857// CmpJSONBody tests that the last request response body can be858// [json.Unmarshal]'ed and that it matches expectedBody. expectedBody859// can be any type one can [json.Unmarshal] into, or a [td.TestDeep]860// operator.861//862// ta := tdhttp.NewTestAPI(t, mux)863//864// ta.Get("/person/42").865// CmpStatus(http.StatusOK).866// CmpJSONBody(Person{867// ID: 42,868// Name: "Bob",869// Age: 26,870// })871//872// ta.PostJSON("/person", Person{Name: "Bob", Age: 23}).873// CmpStatus(http.StatusCreated).874// CmpJSONBody(td.SStruct(875// Person{876// Name: "Bob",877// Age: 26,878// },879// td.StructFields{880// "ID": td.NotZero(),881// }))882//883// The same with anchoring, and so without [td.SStruct]:884//885// ta := tdhttp.NewTestAPI(tt, mux)886//887// ta.PostJSON("/person", Person{Name: "Bob", Age: 23}).888// CmpStatus(http.StatusCreated).889// CmpJSONBody(Person{890// ID: ta.Anchor(td.NotZero(), uint64(0)).(uint64),891// Name: "Bob",892// Age: 26,893// })894//895// The same using [td.JSON]:896//897// ta.PostJSON("/person", Person{Name: "Bob", Age: 23}).898// CmpStatus(http.StatusCreated).899// CmpJSONBody(td.JSON(`900// {901// "id": NotZero(),902// "name": "Bob",903// "age": 26904// }`))905//906// It fails if no request has been sent yet.907func (ta *TestAPI) CmpJSONBody(expectedBody any) *TestAPI {908 ta.t.Helper()909 return ta.CmpMarshaledBody(json.Unmarshal, expectedBody)910}911// CmpXMLBody tests that the last request response body can be912// [xml.Unmarshal]'ed and that it matches expectedBody. expectedBody913// can be any type one can [xml.Unmarshal] into, or a [td.TestDeep]914// operator.915//916// ta := tdhttp.NewTestAPI(t, mux)917//918// ta.Get("/person/42").919// CmpStatus(http.StatusOK).920// CmpXMLBody(Person{921// ID: 42,922// Name: "Bob",923// Age: 26,924// })925//926// ta.Get("/person/43").927// CmpStatus(http.StatusOK).928// CmpXMLBody(td.SStruct(929// Person{930// Name: "Bob",931// Age: 26,932// },933// td.StructFields{934// "ID": td.NotZero(),935// }))936//937// The same with anchoring:938//939// ta := tdhttp.NewTestAPI(tt, mux)940//941// ta.Get("/person/42").942// CmpStatus(http.StatusOK).943// CmpXMLBody(Person{944// ID: ta.Anchor(td.NotZero(), uint64(0)).(uint64),945// Name: "Bob",946// Age: 26,947// })948//949// It fails if no request has been sent yet.950func (ta *TestAPI) CmpXMLBody(expectedBody any) *TestAPI {951 ta.t.Helper()952 return ta.CmpMarshaledBody(xml.Unmarshal, expectedBody)953}954// NoBody tests that the last request response body is empty.955//956// It fails if no request has been sent yet.957func (ta *TestAPI) NoBody() *TestAPI {958 defer ta.t.AnchorsPersistTemporarily()()959 ta.t.Helper()960 if !ta.checkRequestSent() {961 ta.failed |= bodyFailed962 return ta963 }964 ok := ta.t.RootName("Response.Body").965 Code(len(ta.response.Body.Bytes()) == 0,966 func(empty bool) error {...

Full Screen

Full Screen

http.go

Source:http.go Github

copy

Full Screen

1// Copyright (c) 2019, Maxime Soulé2// All rights reserved.3//4// This source code is licensed under the BSD-style license found in the5// LICENSE file in the root directory of this source tree.6package tdhttp7import (8 "encoding/json"9 "encoding/xml"10 "fmt"11 "net/http"12 "reflect"13 "testing"14 "github.com/maxatome/go-testdeep/helpers/tdutil"15 "github.com/maxatome/go-testdeep/internal/trace"16 "github.com/maxatome/go-testdeep/td"17)18func init() {19 trace.IgnorePackage()20}21// Response is used by Cmp*Response functions to make the HTTP22// response match easier. Each field, can be a [td.TestDeep] operator23// as well as the exact expected value.24type Response struct {25 Status any // is the expected status (ignored if nil)26 Header any // is the expected header (ignored if nil)27 Cookies any // is the expected cookies (ignored if nil)28 Body any // is the expected body (expected to be empty if nil)29}30func cmpMarshaledResponse(tb testing.TB,31 req *http.Request,32 handler func(w http.ResponseWriter, r *http.Request),33 acceptEmptyBody bool,34 unmarshal func([]byte, any) error,35 expectedResp Response,36 args ...any,37) bool {38 tb.Helper()39 if testName := tdutil.BuildTestName(args...); testName != "" {40 tb.Log(testName)41 }42 t := td.NewT(tb)43 defer t.AnchorsPersistTemporarily()()44 ta := NewTestAPI(t, http.HandlerFunc(handler)).Request(req)45 // Check status, nil = ignore46 if expectedResp.Status != nil {47 ta.CmpStatus(expectedResp.Status)48 }49 // Check header, nil = ignore50 if expectedResp.Header != nil {51 ta.CmpHeader(expectedResp.Header)52 }53 // Check cookie, nil = ignore54 if expectedResp.Cookies != nil {55 ta.CmpCookies(expectedResp.Cookies)56 }57 if expectedResp.Body == nil {58 ta.NoBody()59 } else {60 ta.cmpMarshaledBody(acceptEmptyBody, unmarshal, expectedResp.Body)61 }62 return !ta.Failed()63}64// CmpMarshaledResponse is the base function used by some others in65// tdhttp package. req is launched against handler. The response body66// is unmarshaled using unmarshal. The response is then tested against67// expectedResp.68//69// args... are optional and allow to name the test, a t.Log() done70// before starting any test. If len(args) > 1 and the first item of71// args is a string and contains a '%' rune then [fmt.Fprintf] is used72// to compose the name, else args are passed to [fmt.Fprint].73//74// It returns true if the tests succeed, false otherwise.75//76// See [TestAPI] type and its methods for more flexible tests.77func CmpMarshaledResponse(t testing.TB,78 req *http.Request,79 handler func(w http.ResponseWriter, r *http.Request),80 unmarshal func([]byte, any) error,81 expectedResp Response,82 args ...any,83) bool {84 t.Helper()85 return cmpMarshaledResponse(t, req, handler, false, unmarshal, expectedResp, args...)86}87// CmpResponse is used to match a []byte or string response body. req88// is launched against handler. If expectedResp.Body is non-nil, the89// response body is converted to []byte or string, depending on the90// expectedResp.Body type. The response is then tested against91// expectedResp.92//93// args... are optional and allow to name the test, a t.Log() done94// before starting any test. If len(args) > 1 and the first item of95// args is a string and contains a '%' rune then [fmt.Fprintf] is used96// to compose the name, else args are passed to [fmt.Fprint].97//98// It returns true if the tests succeed, false otherwise.99//100// ok := tdhttp.CmpResponse(t,101// tdhttp.Get("/test"),102// myAPI.ServeHTTP,103// Response{104// Status: http.StatusOK,105// Header: td.ContainsKey("X-Custom-Header"),106// Body: "OK!\n",107// },108// "/test route")109//110// Response.Status, Response.Header and Response.Body fields can all111// be [td.TestDeep] operators as it is for Response.Header field112// here. Otherwise, Response.Status should be an int, Response.Header113// a [http.Header] and Response.Body a []byte or a string.114//115// See [TestAPI] type and its methods for more flexible tests.116func CmpResponse(t testing.TB,117 req *http.Request,118 handler func(w http.ResponseWriter, r *http.Request),119 expectedResp Response,120 args ...any) bool {121 t.Helper()122 return cmpMarshaledResponse(t,123 req,124 handler,125 true,126 func(body []byte, target any) error {127 switch t := target.(type) {128 case *string:129 *t = string(body)130 case *[]byte:131 *t = body132 case *any:133 *t = body134 default:135 // cmpMarshaledBody (behind cmpMarshaledResponse) always calls136 // us with target as a pointer137 return fmt.Errorf(138 "CmpResponse only accepts expectedResp.Body be a []byte, a string or a TestDeep operator allowing to match these types, but not type %s",139 reflect.TypeOf(target).Elem())140 }141 return nil142 },143 expectedResp,144 args...)145}146// CmpJSONResponse is used to match a JSON response body. req is147// launched against handler. If expectedResp.Body is non-nil, the148// response body is [json.Unmarshal]'ed. The response is then tested149// against expectedResp.150//151// args... are optional and allow to name the test, a t.Log() done152// before starting any test. If len(args) > 1 and the first item of153// args is a string and contains a '%' rune then [fmt.Fprintf] is used154// to compose the name, else args are passed to [fmt.Fprint].155//156// It returns true if the tests succeed, false otherwise.157//158// ok := tdhttp.CmpJSONResponse(t,159// tdhttp.Get("/person/42"),160// myAPI.ServeHTTP,161// Response{162// Status: http.StatusOK,163// Header: td.ContainsKey("X-Custom-Header"),164// Body: Person{165// ID: 42,166// Name: "Bob",167// Age: 26,168// },169// },170// "/person/{id} route")171//172// Response.Status, Response.Header and Response.Body fields can all173// be [td.TestDeep] operators as it is for Response.Header field174// here. Otherwise, Response.Status should be an int, Response.Header175// a [http.Header] and Response.Body any type one can176// [json.Unmarshal] into.177//178// If Response.Status and Response.Header are omitted (or nil), they179// are not tested.180//181// If Response.Body is omitted (or nil), it means the body response has to be182// empty. If you want to ignore the body response, use [td.Ignore]183// explicitly.184//185// See [TestAPI] type and its methods for more flexible tests.186func CmpJSONResponse(t testing.TB,187 req *http.Request,188 handler func(w http.ResponseWriter, r *http.Request),189 expectedResp Response,190 args ...any,191) bool {192 t.Helper()193 return CmpMarshaledResponse(t,194 req,195 handler,196 json.Unmarshal,197 expectedResp,198 args...)199}200// CmpXMLResponse is used to match an XML response body. req201// is launched against handler. If expectedResp.Body is202// non-nil, the response body is [xml.Unmarshal]'ed. The response is203// then tested against expectedResp.204//205// args... are optional and allow to name the test, a t.Log() done206// before starting any test. If len(args) > 1 and the first item of207// args is a string and contains a '%' rune then [fmt.Fprintf] is used208// to compose the name, else args are passed to [fmt.Fprint].209//210// It returns true if the tests succeed, false otherwise.211//212// ok := tdhttp.CmpXMLResponse(t,213// tdhttp.Get("/person/42"),214// myAPI.ServeHTTP,215// Response{216// Status: http.StatusOK,217// Header: td.ContainsKey("X-Custom-Header"),218// Body: Person{219// ID: 42,220// Name: "Bob",221// Age: 26,222// },223// },224// "/person/{id} route")225//226// Response.Status, Response.Header and Response.Body fields can all227// be [td.TestDeep] operators as it is for Response.Header field228// here. Otherwise, Response.Status should be an int, Response.Header229// a [http.Header] and Response.Body any type one can [xml.Unmarshal]230// into.231//232// If Response.Status and Response.Header are omitted (or nil), they233// are not tested.234//235// If Response.Body is omitted (or nil), it means the body response236// has to be empty. If you want to ignore the body response, use237// [td.Ignore] explicitly.238//239// See [TestAPI] type and its methods for more flexible tests.240func CmpXMLResponse(t testing.TB,241 req *http.Request,242 handler func(w http.ResponseWriter, r *http.Request),243 expectedResp Response,244 args ...any,245) bool {246 t.Helper()247 return CmpMarshaledResponse(t,248 req,249 handler,250 xml.Unmarshal,251 expectedResp,252 args...)253}254// CmpMarshaledResponseFunc returns a function ready to be used with255// [testing.T.Run], calling [CmpMarshaledResponse] behind the scene. As it256// is intended to be used in conjunction with [testing.T.Run] which257// names the sub-test, the test name part (args...) is voluntary258// omitted.259//260// t.Run("Subtest name", tdhttp.CmpMarshaledResponseFunc(261// tdhttp.Get("/text"),262// mux.ServeHTTP,263// tdhttp.Response{264// Status: http.StatusOK,265// }))266//267// See [CmpMarshaledResponse] for details.268//269// See [TestAPI] type and its methods for more flexible tests.270func CmpMarshaledResponseFunc(req *http.Request,271 handler func(w http.ResponseWriter, r *http.Request),272 unmarshal func([]byte, any) error,273 expectedResp Response) func(t *testing.T) {274 return func(t *testing.T) {275 t.Helper()276 CmpMarshaledResponse(t, req, handler, unmarshal, expectedResp)277 }278}279// CmpResponseFunc returns a function ready to be used with280// [testing.T.Run], calling [CmpResponse] behind the scene. As it is281// intended to be used in conjunction with [testing.T.Run] which names282// the sub-test, the test name part (args...) is voluntary omitted.283//284// t.Run("Subtest name", tdhttp.CmpResponseFunc(285// tdhttp.Get("/text"),286// mux.ServeHTTP,287// tdhttp.Response{288// Status: http.StatusOK,289// }))290//291// See [CmpResponse] documentation for details.292//293// See [TestAPI] type and its methods for more flexible tests.294func CmpResponseFunc(req *http.Request,295 handler func(w http.ResponseWriter, r *http.Request),296 expectedResp Response) func(t *testing.T) {297 return func(t *testing.T) {298 t.Helper()299 CmpResponse(t, req, handler, expectedResp)300 }301}302// CmpJSONResponseFunc returns a function ready to be used with303// [testing.T.Run], calling [CmpJSONResponse] behind the scene. As it is304// intended to be used in conjunction with [testing.T.Run] which names305// the sub-test, the test name part (args...) is voluntary omitted.306//307// t.Run("Subtest name", tdhttp.CmpJSONResponseFunc(308// tdhttp.Get("/json"),309// mux.ServeHTTP,310// tdhttp.Response{311// Status: http.StatusOK,312// Body: JResp{Comment: "expected comment!"},313// }))314//315// See [CmpJSONResponse] documentation for details.316//317// See [TestAPI] type and its methods for more flexible tests.318func CmpJSONResponseFunc(req *http.Request,319 handler func(w http.ResponseWriter, r *http.Request),320 expectedResp Response) func(t *testing.T) {321 return func(t *testing.T) {322 t.Helper()323 CmpJSONResponse(t, req, handler, expectedResp)324 }325}326// CmpXMLResponseFunc returns a function ready to be used with327// [testing.T.Run], calling [CmpXMLResponse] behind the scene. As it is328// intended to be used in conjunction with [testing.T.Run] which names329// the sub-test, the test name part (args...) is voluntary omitted.330//331// t.Run("Subtest name", tdhttp.CmpXMLResponseFunc(332// tdhttp.Get("/xml"),333// mux.ServeHTTP,334// tdhttp.Response{335// Status: http.StatusOK,336// Body: JResp{Comment: "expected comment!"},337// }))338//339// See [CmpXMLResponse] documentation for details.340//341// See [TestAPI] type and its methods for more flexible tests.342func CmpXMLResponseFunc(req *http.Request,343 handler func(w http.ResponseWriter, r *http.Request),344 expectedResp Response) func(t *testing.T) {345 return func(t *testing.T) {346 t.Helper()347 CmpXMLResponse(t, req, handler, expectedResp)348 }349}...

Full Screen

Full Screen

CmpMarshaledBody

Using AI Code Generation

copy

Full Screen

1import (2func TestCmpMarshaledBody(t *testing.T) {3 t.Run("cmp marshaled body", func(t *testing.T) {4 m := mocks.NewMockHTTPClient()5 On("Do", matchers.CmpMarshaledBody(&http.Request{}, &http.Response{}, &struct {6 Return(nil)7 })8}9import (10func TestCmpMarshaledBody(t *testing.T) {11 t.Run("cmp marshaled body", func(t *testing.T) {12 m := mocks.NewMockHTTPClient()13 On("Do", matchers.CmpMarshaledBody(&http.Request{}, &http.Response{}, &struct {14 Return(nil)15 })16}17import (18func TestCmpMarshaledBody(t *testing.T) {19 t.Run("cmp marshaled body", func(t *testing.T) {20 m := mocks.NewMockHTTPClient()21 On("Do", matchers.CmpMarshaledBody(&http.Request{}, &http.Response{}, &struct {22 Return(nil)23 })24}25import (

Full Screen

Full Screen

CmpMarshaledBody

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 tdhttp.CmpMarshaledBody([]byte(`{"a":1,"b":"c"}`), []byte(`{"a":1,"b":"c"}`))4 fmt.Println("Hello, playground")5}6import (7func main() {8 tdhttp.CmpMarshaledBody([]byte(`{"a":1,"b":"c"}`), []byte(`{"a":1,"b":"d"}`))9 fmt.Println("Hello, playground")10}11import (12func main() {13 tdhttp.CmpMarshaledBody([]byte(`{"a":1,"b":"c"}`), []byte(`{"a":1,"b":"c","c":"d"}`))14 fmt.Println("Hello, playground")15}16import (17func main() {18 tdhttp.CmpMarshaledBody([]byte(`{"a":1,"b":"c"}`), []byte(`{"a":1,"b":"c","c":null}`))19 fmt.Println("Hello, playground")20}21import (22func main() {23 tdhttp.CmpMarshaledBody([]byte(`{"a":1,"b":"c"}`), []byte(`{"a":1,"b":"c","c":[]}`))24 fmt.Println("Hello, playground")25}26import (

Full Screen

Full Screen

CmpMarshaledBody

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 resp, err := r.Send()4 if err != nil {5 fmt.Println(err)6 }7 fmt.Println(resp.CmpMarshaledBody(`{"args":{},"headers":{"Accept-Encoding":"gzip","Connection":"close","Host":"httpbin.org","User-Agent":"tdhttp/1.0.0 (

Full Screen

Full Screen

CmpMarshaledBody

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 if tdhttp.CmpMarshaledBody(req1, req2) {4 fmt.Println("The marshaled body of two requests are equal")5 } else {6 fmt.Println("The marshaled body of two requests are not equal")7 }8}

Full Screen

Full Screen

CmpMarshaledBody

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 td := tdhttp.New()4 td.SetMethod("GET")5 td.SetHeaders(map[string]string{6 })7 td.SetBody([]byte(`{}`))8 td.SetExpectedStatus(200)9 td.SetExpectedBody([]byte(`{"login":"tdakkota","id":1663140,"node_id":"MDQ6VXNlcjE2NjMxNDA="}`))10 td.SetExpectedHeaders(map[string]string{11 })12 td.SetExpectedReason("OK")13 td.SetExpectedContentType("application/json")14 td.SetExpectedContentLength(69)15 td.SetExpectedBody([]byte(`{"login":"tdakkota","id":1663140,"node_id":"MDQ6VXNlcjE2NjMxNDA="}`))16 td.SetExpectedBody([]byte(`{"login":"tdakkota","id":1663140,"node_id":"MDQ6VXNlcjE2NjMxNDA="}`))17 td.SetExpectedBody([]byte(`{"login":"tdakkota","id":1663140,"node_id":"MDQ6VXNlcjE2NjMxNDA="}`))18 td.SetExpectedBody([]byte(`{"login":"tdakkota","id":1663140,"node_id":"MDQ6VXNlcjE2NjMxNDA="}`))19 td.SetExpectedBody([]byte(`{"login":"tdakkota","id":1663140,"node_id":"MDQ6VXNlcjE2N

Full Screen

Full Screen

CmpMarshaledBody

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 tdhttpObj := tdhttp.NewTDHttp()4 tdhttpObj.SetMethod("GET")5 tdhttpObj.SetRequestBody("")6 tdhttpObj.SetRequestHeader("Content-Type", "application/json")7 tdhttpObj.SetRequestTimeout(5)

Full Screen

Full Screen

CmpMarshaledBody

Using AI Code Generation

copy

Full Screen

1type TestResponse struct {2}3func TestCmpMarshaledBody(t *testing.T) {4 actual := TestResponse{Code: 200, Body: "hello world"}5 expected := TestResponse{Code: 200, Body: "hello world"}6 err := tdhttp.CmpMarshaledBody(actual, expected)7 if err != nil {8 t.Error(err)9 }10}11type TestResponse struct {12}13func TestCmpMarshaledBody(t *testing.T) {14 actual := TestResponse{Code: 200, Body: "hello world"}15 expected := TestResponse{Code: 200, Body: "hello world"}16 err := tdhttp.CmpMarshaledBody(actual, expected)17 if err != nil {18 t.Error(err)19 }20}21type TestResponse struct {22}23func TestCmpMarshaledBody(t *testing.T) {24 actual := TestResponse{Code: 200, Body: "hello world"}25 expected := TestResponse{Code: 200, Body: "hello world"}26 err := tdhttp.CmpMarshaledBody(actual, expected)27 if err != nil {28 t.Error(err)29 }30}31type TestResponse struct {32}33func TestCmpMarshaledBody(t *testing.T) {34 actual := TestResponse{Code: 200, Body: "hello world"}35 expected := TestResponse{Code: 200, Body: "hello world"}

Full Screen

Full Screen

CmpMarshaledBody

Using AI Code Generation

copy

Full Screen

1func main() {2 tc := tdhttp.NewTestCase("Test Case")3 req.SetMarshaledBody([]byte(`{"name":"test","age":20}`))4 tc.AddRequest(req)5 res := tdhttp.NewResponse(200)6 res.SetMarshaledBody([]byte(`{"name":"test","age":20}`))7 tc.AddResponse(res)8 td := tdhttp.NewTestData("Test Data")9 td.AddTestCase(tc)10 ts := tdhttp.NewTestSuite("Test Suite")11 ts.AddTestData(td)12 td := tdhttp.NewTestDescriptor("Test Descriptor")13 td.AddTestSuite(ts)14 tdr := tdhttp.NewTestDescriptorRunner()15 tdr.Run(td)16}17func main() {18 tc := tdhttp.NewTestCase("Test Case")19 req.SetMarshaledBody([]byte(`{"name":"test","age":20}`))20 tc.AddRequest(req)21 res := tdhttp.NewResponse(200)22 res.SetMarshaledBody([]byte(`{"name":"test","age":20}`

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful