How to use Migrate method of migrator Package

Best Testkube code snippet using migrator.Migrate

migrate.go

Source:migrate.go Github

copy

Full Screen

...4 "fmt"5 "sync"6 "time"7)8// MigrateState is exported9type MigrateState int10const (11 MigrateReady = iota + 112 Migrating13 MigrateFailure14 MigrateCompleted15)16func (state MigrateState) String() string {17 switch state {18 case MigrateReady:19 return "MigrateReady"20 case Migrating:21 return "Migrating"22 case MigrateFailure:23 return "MigrateFailure"24 case MigrateCompleted:25 return "MigrateCompleted"26 }27 return ""28}29// MigrateContainer is exported30type MigrateContainer struct {31 sync.RWMutex32 ID string33 metaData *MetaData34 baseConfig *ContainerBaseConfig35 filter *EnginesFilter36 state MigrateState37}38// NewMigrateContainer is exported39func NewMigrateContainer(containerid string, baseConfig *ContainerBaseConfig) *MigrateContainer {40 if baseConfig == nil || baseConfig.MetaData == nil {41 return nil42 }43 return &MigrateContainer{44 ID: containerid,45 metaData: baseConfig.MetaData,46 baseConfig: baseConfig,47 filter: NewEnginesFilter(),48 state: MigrateReady,49 }50}51// GetState is exported52func (mContainer *MigrateContainer) GetState() MigrateState {53 mContainer.RLock()54 defer mContainer.RUnlock()55 return mContainer.state56}57// SetState is exported58func (mContainer *MigrateContainer) SetState(state MigrateState) {59 mContainer.Lock()60 mContainer.state = state61 mContainer.Unlock()62}63// Execute is exported64func (mContainer *MigrateContainer) Execute(cluster *Cluster) {65 mContainer.SetState(Migrating)66 mContainer.baseConfig.ID = "" //re-create a new container67 engine, container, err := cluster.createContainer(mContainer.metaData, mContainer.filter, nil, mContainer.baseConfig.Container)68 if err != nil {69 mContainer.SetState(MigrateFailure)70 logger.ERROR("[#cluster] migrator container %s error %s", ShortContainerID(mContainer.ID), err.Error())71 return72 }73 mContainer.Lock()74 mContainer.state = MigrateCompleted75 logger.INFO("[#cluster] migrator container %s > %s to %s", ShortContainerID(mContainer.ID), ShortContainerID(container.Info.ID), engine.IP)76 mContainer.Unlock()77 return78}79// Migrator is exported80type Migrator struct {81 sync.RWMutex82 MetaID string83 Cluster *Cluster84 retryCount int6485 migrateDelay time.Duration86 containers []*MigrateContainer87 handler MigratorHandler88}89// NewMigrator is exported90func NewMigrator(metaid string, containers Containers, cluster *Cluster, migrateDelay time.Duration, handler MigratorHandler) *Migrator {91 mContainers := []*MigrateContainer{}92 for _, container := range containers {93 mContainer := NewMigrateContainer(container.Info.ID, container.BaseConfig)94 if mContainer != nil {95 mContainers = append(mContainers, mContainer)96 }97 }98 return &Migrator{99 MetaID: metaid,100 Cluster: cluster,101 retryCount: cluster.createRetry,102 migrateDelay: migrateDelay,103 containers: mContainers,104 handler: handler,105 }106}107func (migrator *Migrator) verifyEngines() bool {108 _, engines, err := migrator.Cluster.GetMetaDataEngines(migrator.MetaID)109 if err != nil {110 return false111 }112 for _, engine := range engines {113 if engine.IsHealthy() {114 return true115 }116 }117 return false118}119func (migrator *Migrator) isAllCompleted() bool {120 migrator.RLock()121 defer migrator.RUnlock()122 for _, mContainer := range migrator.containers {123 if mContainer.GetState() != MigrateCompleted {124 return false125 }126 }127 return true128}129func (migrator *Migrator) isPartCompleted() bool {130 migrator.RLock()131 defer migrator.RUnlock()132 nCompletedCount := 0133 for _, mContainer := range migrator.containers {134 if mContainer.GetState() == MigrateCompleted {135 nCompletedCount = nCompletedCount + 1136 }137 }138 if nCompletedCount == 0 {139 return false140 }141 return nCompletedCount != len(migrator.containers)142}143func (migrator *Migrator) resetMigrateContainers() {144 migrator.Lock()145 for _, mContainer := range migrator.containers {146 if mContainer.GetState() == MigrateFailure {147 mContainer.SetState(MigrateReady)148 }149 }150 migrator.retryCount = migrator.retryCount - 1151 migrator.Unlock()152}153func (migrator *Migrator) selectMigrateContainer() *MigrateContainer {154 migrator.RLock()155 defer migrator.RUnlock()156 for _, mContainer := range migrator.containers {157 if mContainer.GetState() == MigrateReady {158 return mContainer159 }160 }161 return nil162}163func (migrator *Migrator) removeMigrateContainer(mContainer *MigrateContainer) {164 migrator.Lock()165 for i, pmContainer := range migrator.containers {166 if pmContainer == mContainer {167 migrator.containers = append(migrator.containers[:i], migrator.containers[i+1:]...)168 break169 }170 }171 migrator.Unlock()172}173func (migrator *Migrator) clearMigrateContainers() {174 migrator.Lock()175 migrator.containers = []*MigrateContainer{}176 migrator.Unlock()177}178// Containers is exported179func (migrator *Migrator) Containers() []*MigrateContainer {180 migrator.RLock()181 mContainers := []*MigrateContainer{}182 for _, mContainer := range migrator.containers {183 mContainers = append(mContainers, mContainer)184 }185 migrator.RUnlock()186 return mContainers187}188// Container is exported189func (migrator *Migrator) Container(containerid string) *MigrateContainer {190 migrator.RLock()191 defer migrator.RUnlock()192 for _, mContainer := range migrator.containers {193 if mContainer.ID == containerid {194 return mContainer195 }196 }197 return nil198}199// Start is exported200func (migrator *Migrator) Start() {201 time.Sleep(migrator.migrateDelay)202 for {203 migrator.RLock()204 mContainers := migrator.containers205 migrator.RUnlock()206 if len(mContainers) == 0 {207 break208 }209 if !migrator.isAllCompleted() {210 if !migrator.verifyEngines() {211 err := fmt.Errorf("cluster no docker-engine available")212 logger.ERROR("[#cluster] migrator %s containers error %s.", migrator.MetaID, err)213 migrator.clearMigrateContainers()214 migrator.Cluster.configCache.ClearContainerBaseConfig(migrator.MetaID)215 migrator.handler.OnMigratorNotifyHandleFunc(migrator, err)216 break217 }218 }219 mContainer := migrator.selectMigrateContainer()220 if mContainer != nil {221 mContainer.Execute(migrator.Cluster)222 if mContainer.GetState() == MigrateCompleted {223 migrator.Cluster.configCache.RemoveContainerBaseConfig(migrator.MetaID, mContainer.ID)224 }225 continue226 }227 if migrator.isAllCompleted() {228 migrator.handler.OnMigratorNotifyHandleFunc(migrator, nil)229 break230 }231 if migrator.retryCount <= 0 {232 migrator.Lock()233 for _, mContainer := range migrator.containers {234 if mContainer.GetState() == MigrateFailure {235 migrator.Cluster.configCache.RemoveContainerBaseConfig(migrator.MetaID, mContainer.ID)236 }237 }238 migrator.Unlock()239 migrator.handler.OnMigratorNotifyHandleFunc(migrator, fmt.Errorf("meta containers part migrated failure."))240 break241 }242 if migrator.isPartCompleted() {243 migrator.handler.OnMigratorNotifyHandleFunc(migrator, fmt.Errorf("meta containers part migrated completed."))244 }245 migrator.resetMigrateContainers()246 continue247 }248 migrator.clearMigrateContainers()249 migrator.handler.OnMigratorQuitHandleFunc(migrator)250}251// Update is exported252func (migrator *Migrator) Update(metaid string, containers Containers) {253 for _, container := range containers {254 if mContainer := migrator.Container(container.Info.ID); mContainer == nil {255 mContainer = NewMigrateContainer(container.Info.ID, container.BaseConfig)256 if mContainer != nil {257 migrator.Lock()258 migrator.containers = append(migrator.containers, mContainer)259 migrator.Unlock()260 }261 }262 }263}264// Cancel is exported265func (migrator *Migrator) Cancel(metaid string, containers Containers) {266 for _, container := range containers {267 if mContainer := migrator.Container(container.Info.ID); mContainer != nil {268 state := mContainer.GetState()269 if state == MigrateReady || state == MigrateFailure {270 migrator.removeMigrateContainer(mContainer)271 }272 }273 }274}275// Clear is exported276func (migrator *Migrator) Clear() {277 migrator.Lock()278 migrator.containers = []*MigrateContainer{}279 migrator.Unlock()280}281// MigratorHandler is exported282type MigratorHandler interface {283 OnMigratorQuitHandleFunc(migrator *Migrator)284 OnMigratorNotifyHandleFunc(migrator *Migrator, err error)285}286// MigratorQuitHandleFunc is exported287type MigratorQuitHandleFunc func(migrator *Migrator)288// OnMigratorQuitHandleFunc is exported289func (fn MigratorQuitHandleFunc) OnMigratorQuitHandleFunc(migrator *Migrator) {290 fn(migrator)291}292// MigratorNotifyHandleFunc is exported293type MigratorNotifyHandleFunc func(migrator *Migrator, err error)294// OnMigratorNotifyHandleFunc is exported295func (fn MigratorNotifyHandleFunc) OnMigratorNotifyHandleFunc(migrator *Migrator, err error) {296 fn(migrator, err)297}298// MigrateContainersCache is exported299type MigrateContainersCache struct {300 sync.RWMutex301 MigratorHandler302 Cluster *Cluster303 migrateDelay time.Duration304 migrators map[string]*Migrator305}306// NewMigrateContainersCache is exported307func NewMigrateContainersCache(migrateDelay time.Duration) *MigrateContainersCache {308 return &MigrateContainersCache{309 migrateDelay: migrateDelay,310 migrators: make(map[string]*Migrator),311 }312}313// SetCluster is exported314func (cache *MigrateContainersCache) SetCluster(cluster *Cluster) {315 cache.Cluster = cluster316}317// Contains is exported318func (cache *MigrateContainersCache) Contains(metaid string) bool {319 cache.RLock()320 defer cache.RUnlock()321 _, ret := cache.migrators[metaid]322 return ret323}324// RemoveGroup is exported325// cancel group all metadata migrate.326func (cache *MigrateContainersCache) RemoveGroup(groupid string) {327 cache.RLock()328 groupMetaData := cache.Cluster.configCache.GetGroupMetaData(groupid)329 for _, metaData := range groupMetaData {330 if migrator, ret := cache.migrators[metaData.MetaID]; ret {331 migrator.Clear()332 logger.INFO("[#cluster] migrator clear %s", migrator.MetaID)333 }334 }335 cache.RUnlock()336}337// Start is exported338// engine offline, start migrate containers.339// engine parameter is offline engine pointer.340func (cache *MigrateContainersCache) Start(engine *Engine) {341 if engine.IsHealthy() {342 metaids := engine.MetaIds()343 cache.start(engine, metaids)344 }345}346// Cancel is exported347// engine online, cancel migrate containers of state is MigrateReady.348// engine parameter is online engine pointer.349func (cache *MigrateContainersCache) Cancel(engine *Engine) {350 if engine.IsHealthy() {351 metaids := engine.MetaIds()352 cache.cancel(engine, metaids)353 }354}355func (cache *MigrateContainersCache) start(engine *Engine, metaids []string) {356 if len(metaids) > 0 {357 cache.Lock()358 for _, metaid := range metaids {359 containers := engine.Containers(metaid)360 if len(containers) == 0 {361 continue362 }363 migrator, ret := cache.migrators[metaid]364 if !ret {365 migrator = NewMigrator(metaid, containers, cache.Cluster, cache.migrateDelay, cache)366 cache.migrators[metaid] = migrator367 logger.INFO("[#cluster] migrator start %s %s", engine.IP, metaid)368 go migrator.Start()369 } else {370 logger.INFO("[#cluster] migrator update %s %s", engine.IP, metaid)371 migrator.Update(metaid, containers)372 }373 }374 cache.Unlock()375 }376}377func (cache *MigrateContainersCache) cancel(engine *Engine, metaids []string) {378 if len(metaids) > 0 {379 cache.RLock()380 waitgroup := sync.WaitGroup{}381 for _, metaid := range metaids {382 if migrator, ret := cache.migrators[metaid]; ret {383 containers := engine.Containers(metaid)384 if len(containers) == 0 {385 continue386 }387 waitgroup.Add(1)388 go func(id string, c Containers) {389 defer waitgroup.Done()390 logger.INFO("[#cluster] migrator cancel %s %s", engine.IP, id)391 migrator.Cancel(id, c)392 }(metaid, containers)393 }394 }395 waitgroup.Wait()396 cache.RUnlock()397 }398}399// OnMigratorQuitHandleFunc is exported400func (cache *MigrateContainersCache) OnMigratorQuitHandleFunc(migrator *Migrator) {401 logger.INFO("[#cluster] migrator quited %s", migrator.MetaID)402 cache.Lock()403 delete(cache.migrators, migrator.MetaID)404 cache.Unlock()405}406// OnMigratorNotifyHandleFunc is exported407func (cache *MigrateContainersCache) OnMigratorNotifyHandleFunc(migrator *Migrator, err error) {408 logger.INFO("[#cluster] migrator notify %s", migrator.MetaID)409 metaData := cache.Cluster.GetMetaData(migrator.MetaID)410 cache.Cluster.submitHookEvent(metaData, MigrateMetaEvent)411 cache.Cluster.NotifyGroupMetaContainersEvent("Cluster Meta Containers Migrated.", err, migrator.MetaID)412 mContainers := migrator.Containers()413 for _, mContainer := range mContainers {414 logger.INFO("[#cluster] migrator container %s %s", ShortContainerID(mContainer.ID), mContainer.state.String())415 }416}...

Full Screen

Full Screen

migrator_test.go

Source:migrator_test.go Github

copy

Full Screen

...38 }39 })40 Context("migrating users table", func() {41 BeforeEach(func() {42 mockMigrator.MigrateUsersTableReturns(errors.New("failed to migrate"))43 })44 It("rolls back transaction if migration fails", func() {45 db.Migrate(mockMigrator, currentLevels, srvLevels)46 Expect(mockMigrator.RollbackCallCount()).To(Equal(1))47 })48 It("returns an error if rolling back transaction fails", func() {49 mockMigrator.RollbackReturns(errors.New("failed to rollback"))50 err := db.Migrate(mockMigrator, currentLevels, srvLevels)51 Expect(err).To(HaveOccurred())52 Expect(err.Error()).To(Equal("failed to rollback"))53 })54 })55 Context("migrating affiliations table", func() {56 BeforeEach(func() {57 mockMigrator.MigrateAffiliationsTableReturns(errors.New("failed to migrate"))58 })59 It("rolls back transaction if migration fails", func() {60 db.Migrate(mockMigrator, currentLevels, srvLevels)61 Expect(mockMigrator.RollbackCallCount()).To(Equal(1))62 })63 It("returns an error if rolling back transaction fails", func() {64 mockMigrator.RollbackReturns(errors.New("failed to rollback"))65 err := db.Migrate(mockMigrator, currentLevels, srvLevels)66 Expect(err).To(HaveOccurred())67 Expect(err.Error()).To(Equal("failed to rollback"))68 })69 })70 Context("migrating certificates table", func() {71 BeforeEach(func() {72 mockMigrator.MigrateCertificatesTableReturns(errors.New("failed to migrate"))73 })74 It("rolls back transaction if migration fails", func() {75 db.Migrate(mockMigrator, currentLevels, srvLevels)76 Expect(mockMigrator.RollbackCallCount()).To(Equal(1))77 })78 It("returns an error if rolling back transaction fails", func() {79 mockMigrator.RollbackReturns(errors.New("failed to rollback"))80 err := db.Migrate(mockMigrator, currentLevels, srvLevels)81 Expect(err).To(HaveOccurred())82 Expect(err.Error()).To(Equal("failed to rollback"))83 })84 })85 Context("migrating credentials table", func() {86 BeforeEach(func() {87 mockMigrator.MigrateCredentialsTableReturns(errors.New("failed to migrate"))88 })89 It("rolls back transaction if migration fails", func() {90 db.Migrate(mockMigrator, currentLevels, srvLevels)91 Expect(mockMigrator.RollbackCallCount()).To(Equal(1))92 })93 It("returns an error if rolling back transaction fails", func() {94 mockMigrator.RollbackReturns(errors.New("failed to rollback"))95 err := db.Migrate(mockMigrator, currentLevels, srvLevels)96 Expect(err).To(HaveOccurred())97 Expect(err.Error()).To(Equal("failed to rollback"))98 })99 })100 Context("migrating nonce table", func() {101 BeforeEach(func() {102 mockMigrator.MigrateNoncesTableReturns(errors.New("failed to migrate"))103 })104 It("rolls back transaction if migration fails", func() {105 db.Migrate(mockMigrator, currentLevels, srvLevels)106 Expect(mockMigrator.RollbackCallCount()).To(Equal(1))107 })108 It("returns an error if rolling back transaction fails", func() {109 mockMigrator.RollbackReturns(errors.New("failed to rollback"))110 err := db.Migrate(mockMigrator, currentLevels, srvLevels)111 Expect(err).To(HaveOccurred())112 Expect(err.Error()).To(Equal("failed to rollback"))113 })114 })115 Context("migrating rainfo table", func() {116 BeforeEach(func() {117 mockMigrator.MigrateRAInfoTableReturns(errors.New("failed to migrate"))118 })119 It("rolls back transaction if migration fails", func() {120 db.Migrate(mockMigrator, currentLevels, srvLevels)121 Expect(mockMigrator.RollbackCallCount()).To(Equal(1))122 })123 It("returns an error if rolling back transaction fails", func() {124 mockMigrator.RollbackReturns(errors.New("failed to rollback"))125 err := db.Migrate(mockMigrator, currentLevels, srvLevels)126 Expect(err).To(HaveOccurred())127 Expect(err.Error()).To(Equal("failed to rollback"))128 })129 })130 It("migrates database to the level of the server", func() {131 err := db.Migrate(mockMigrator, currentLevels, srvLevels)132 fmt.Println("err: ", err)133 Expect(err).NotTo(HaveOccurred())134 })135})...

Full Screen

Full Screen

migrate_test.go

Source:migrate_test.go Github

copy

Full Screen

...6 "go-gin-api/pkg/migrate"7 "gorm.io/gorm"8 "testing"9)10func TestMigrate(t *testing.T) {11 boot.Init()12 type TestTable1 struct {13 Id int14 Name string15 }16 type TestTable2 struct {17 Id int18 Name string19 }20 Convey("database migration", t, func() {21 migrate.Add(migrate.MigrationFile{22 FileName: "test_create_test_table_1",23 Up: func(db *gorm.DB) error {24 return db.Migrator().AutoMigrate(&TestTable1{})25 },26 Down: func(db *gorm.DB) error {27 return db.Migrator().DropTable(&TestTable1{})28 },29 }, "default")30 migrate.Add(migrate.MigrationFile{31 FileName: "test_create_test_table_1",32 Up: func(db *gorm.DB) error {33 return db.Migrator().AutoMigrate(&TestTable1{})34 },35 Down: func(db *gorm.DB) error {36 return db.Migrator().DropTable(&TestTable1{})37 },38 }, "test")39 migrate.Run(migrate.Up)40 So(g.DB().Migrator().HasTable(&migrate.Migration{}), ShouldEqual, true)41 So(g.DB().Migrator().HasTable(&TestTable1{}), ShouldEqual, true)42 So(g.DB("test").Migrator().HasTable(&migrate.Migration{}), ShouldEqual, true)43 So(g.DB("test").Migrator().HasTable(&TestTable1{}), ShouldEqual, true)44 migrate.Add(migrate.MigrationFile{45 FileName: "test_create_test_table_2",46 Up: func(db *gorm.DB) error {47 return db.Migrator().AutoMigrate(&TestTable2{})48 },49 Down: func(db *gorm.DB) error {50 return db.Migrator().DropTable(&TestTable2{})51 },52 }, "default")53 migrate.Run(migrate.Up)54 So(g.DB().Migrator().HasTable(&TestTable1{}), ShouldEqual, true)55 So(g.DB().Migrator().HasTable(&TestTable2{}), ShouldEqual, true)56 So(g.DB("test").Migrator().HasTable(&TestTable1{}), ShouldEqual, true)57 migrate.Run(migrate.Reset)58 So(g.DB().Migrator().HasTable(&TestTable1{}), ShouldEqual, false)59 So(g.DB().Migrator().HasTable(&TestTable2{}), ShouldEqual, false)60 So(g.DB("test").Migrator().HasTable(&TestTable1{}), ShouldEqual, false)61 migrate.Run(migrate.Up)62 So(g.DB().Migrator().HasTable(&TestTable1{}), ShouldEqual, true)63 So(g.DB().Migrator().HasTable(&TestTable2{}), ShouldEqual, true)64 So(g.DB("test").Migrator().HasTable(&TestTable1{}), ShouldEqual, true)65 migrate.Add(migrate.MigrationFile{66 FileName: "test_create_test_table_2",67 Up: func(db *gorm.DB) error {68 return db.Migrator().AutoMigrate(&TestTable2{})69 },70 Down: func(db *gorm.DB) error {71 return db.Migrator().DropTable(&TestTable2{})72 },73 }, "test")74 migrate.Run(migrate.Up)75 So(g.DB().Migrator().HasTable(&TestTable1{}), ShouldEqual, true)76 So(g.DB().Migrator().HasTable(&TestTable2{}), ShouldEqual, true)77 So(g.DB("test").Migrator().HasTable(&TestTable1{}), ShouldEqual, true)78 So(g.DB("test").Migrator().HasTable(&TestTable2{}), ShouldEqual, true)79 migrate.Run(migrate.Rollback)80 So(g.DB().Migrator().HasTable(&TestTable1{}), ShouldEqual, false)81 So(g.DB().Migrator().HasTable(&TestTable2{}), ShouldEqual, false)82 So(g.DB("test").Migrator().HasTable(&TestTable1{}), ShouldEqual, true)...

Full Screen

Full Screen

Migrate

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 db, err := gorm.Open("sqlite3", "test.db")4 if err != nil {5 log.Fatal(err)6 }7 defer db.Close()8 migrator := db.Migrator()9 migrator.Migrate(&User{})10}11import (12func main() {13 db, err := gorm.Open("sqlite3", "test.db")14 if err != nil {15 log.Fatal(err)16 }17 defer db.Close()18 migrator := db.Migrator()19 if migrator.HasTable(&User{}) {20 log.Println("Table exists")21 } else {22 log.Println("Table does not exist")23 }24}25import (26func main() {27 db, err := gorm.Open("sqlite3", "test.db")28 if err != nil {29 log.Fatal(err)30 }31 defer db.Close()32 migrator := db.Migrator()33 migrator.RenameTable("users", "employees")34}35import (36func main() {37 db, err := gorm.Open("sqlite3", "test.db")38 if err != nil {39 log.Fatal(err)40 }41 defer db.Close()42 migrator := db.Migrator()43 migrator.DropTable(&User{})44}

Full Screen

Full Screen

Migrate

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 db, err := gorm.Open("sqlite3", "test.db")4 if err != nil {5 panic("failed to connect database")6 }7 defer db.Close()8 migrator := db.Migrator()9 migrator.Migrate()10}11[2019-12-23 15:06:16] [1.26ms] CREATE TABLE "users" ("id" integer,"created_at" datetime,"updated_at" datetime,"deleted_at" datetime,"name" varchar(255),"age" integer,"birthday" datetime,"member_number" varchar(255),"num" integer,"num_point" integer,"company_id" integer,"role" varchar(255) )12[2019-12-23 15:06:16] [0.83ms] CREATE INDEX "idx_users_deleted_at" ON "users" ("deleted_at")13[2019-12-23 15:06:16] [0.80ms] CREATE TABLE "companies" ("id" integer,"created_at" datetime,"updated_at" datetime,"deleted_at" datetime,"name" varchar(255) )14[2019-12-23 15:06:16] [0.81ms] CREATE INDEX "idx_companies_deleted_at" ON "companies" ("deleted_at")15[2019-12-23 15:06:16] [0.83ms] CREATE TABLE "addresses" ("id" integer,"created_at" datetime,"updated_at" datetime,"deleted_at" datetime,"city" varchar(255),"state" varchar(255),"country" varchar(255),"user_id" integer )16[2019-12-23 15:06:16] [0.80ms] CREATE INDEX "idx_addresses_deleted_at" ON "addresses" ("deleted_at")

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.

Run Testkube automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful