Siêu thị PDFTải ngay đi em, trời tối mất

Thư viện tri thức trực tuyến

Kho tài liệu với 50,000+ tài liệu học thuật

© 2023 Siêu thị PDF - Kho tài liệu học thuật hàng đầu Việt Nam

Tài liệu The RSpec Book: Behaviour Driven Development with Rspec, Cucumber, and Friends pptx
PREMIUM
Số trang
426
Kích thước
7.0 MB
Định dạng
PDF
Lượt xem
1334

Tài liệu The RSpec Book: Behaviour Driven Development with Rspec, Cucumber, and Friends pptx

Nội dung xem thử

Mô tả chi tiết

Download from Wow! eBook <www.wowebook.com>

www.it-ebooks.info

What Readers Are Saying About

The RSpec Book: Behaviour-Driven Development with

RSpec, Cucumber, and Friends

The RSpec Book is a fantastic introduction to all things BDD. It goes

much deeper than just testing to provide you with the right tools you

need to fully embrace the ideas that the framework has baked in.

Aaron Bedra, principal, Relevance Inc.

This book covers the territory of writing great software, and the

authors are your experienced guides. If you follow the map that they

have drawn, you’ll learn to write only the code that you need, and

you’ll write it simply and clearly. You’ll come home from this journey

with some experiences that will have immediate and lasting effects on

the code in your editor and the code yet to flow from your fingertips.

Craig Demyanovich, 8th Light, Inc.

The RSpec Book teaches you much more than how to use RSpec’s fea￾tures; it teaches you how to write code the way the RSpec team does:

patiently, and with great precision and clarity. There is something

here for everyone: beginners are given plenty of gentle attention but

there is some real meat for the more experienced reader to chew on,

too.

Matt Wynne, independent programmer and coach

The second generation of tools for the XP generation explained by their

creators and maintainers. Awesome, a must read.

Marcus Ahvne, software developer, Valtech

Some authors would be satisfied with just writing the definitive guide

for a technology. These folks go a step further, and show you insider

tips that will keep your tests clean and maintainable.

Ian Dees, Software Engineer

Download from Wow! eBook <www.wowebook.com>

www.it-ebooks.info

The RSpec Book

Behaviour-Driven Development

with RSpec, Cucumber, and Friends

David Chelimsky

with Dave Astels

Zach Dennis

Aslak Hellesøy

Bryan Helmkamp

Dan North

The Pragmatic Bookshelf

Raleigh, North Carolina Dallas, Texas

Download from Wow! eBook <www.wowebook.com>

www.it-ebooks.info

Many of the designations used by manufacturers and sellers to distinguish their prod￾ucts are claimed as trademarks. Where those designations appear in this book, and The

Pragmatic Programmers, LLC was aware of a trademark claim, the designations have

been printed in initial capital letters or in all capitals. The Pragmatic Starter Kit, The

Pragmatic Programmer, Pragmatic Programming, Pragmatic Bookshelf and the linking g

device are trademarks of The Pragmatic Programmers, LLC.

Every precaution was taken in the preparation of this book. However, the publisher

assumes no responsibility for errors or omissions, or for damages that may result from

the use of information (including program listings) contained herein.

Our Pragmatic courses, workshops, and other products can help you and your team

create better software and have more fun. For more information, as well as the latest

Pragmatic titles, please visit us at http://www.pragprog.com.

The team that produced this book includes:

Editor: Jacquelyn Carter

Indexing: Potomac Indexing, LLC

Copy edit: Kim Wimpsett

Layout: Steve Peter

Production: Janet Furlow

Customer support: Ellie Callahan

International: Juliet Benda

Copyright © 2010 David Chelimsky, Dave Astels, Zach Dennis, Aslak Hellesøy, Bryan

Helmkamp, and Dan North.

All rights reserved.

No part of this publication may be reproduced, stored in a retrieval system, or transmit￾ted, in any form, or by any means, electronic, mechanical, photocopying, recording, or

otherwise, without the prior consent of the publisher.

Printed in the United States of America.

ISBN-10: 1-934356-37-9

ISBN-13: 978-1-934356-37-1

Printed on acid-free paper.

P1.0 printing, December 2010

Version: 2010-11-24

Download from Wow! eBook <www.wowebook.com>

www.it-ebooks.info

Contents

Foreword 11

About the Authors 14

Acknowledgments 16

Preface 18

Ruby and Gem Versions . . . . . . . . . . . . . . . . . . . . 18

Downloading the Code Examples . . . . . . . . . . . . . . . 19

What’s in This Book . . . . . . . . . . . . . . . . . . . . . . 19

I Getting Started with RSpec and Cucumber 21

1 Introduction 22

1.1 Test-Driven Development: Where It All Started . . . 22

1.2 Behaviour-Driven Development: The Next Step . . . 24

1.3 RSpec . . . . . . . . . . . . . . . . . . . . . . . . . . . 25

1.4 Cucumber . . . . . . . . . . . . . . . . . . . . . . . . 26

1.5 The BDD Cycle . . . . . . . . . . . . . . . . . . . . . . 28

2 Hello 30

2.1 Installation . . . . . . . . . . . . . . . . . . . . . . . . 30

2.2 Hello RSpec . . . . . . . . . . . . . . . . . . . . . . . 31

2.3 Hello Cucumber . . . . . . . . . . . . . . . . . . . . . 33

3 Describing Features 37

3.1 Introducing Codebreaker . . . . . . . . . . . . . . . . 38

3.2 Planning the First Release . . . . . . . . . . . . . . . 38

3.3 Planning the First Iteration . . . . . . . . . . . . . . 44

3.4 What We’ve Learned . . . . . . . . . . . . . . . . . . . 52

Download from Wow! eBook <www.wowebook.com>

www.it-ebooks.info

CONTENTS 6

4 Automating Features with Cucumber 53

4.1 Steps and Step Definitions . . . . . . . . . . . . . . . 55

4.2 Step Definition Methods . . . . . . . . . . . . . . . . 56

4.3 Test Double . . . . . . . . . . . . . . . . . . . . . . . 60

4.4 What We’ve Learned . . . . . . . . . . . . . . . . . . . 62

5 Describing Code with RSpec 63

5.1 Getting Started with RSpec . . . . . . . . . . . . . . 63

5.2 Red: Start with a Failing Code Example . . . . . . . 66

5.3 Green: Get the Example to Pass . . . . . . . . . . . . 68

5.4 Refactor . . . . . . . . . . . . . . . . . . . . . . . . . . 72

5.5 What We’ve Learned . . . . . . . . . . . . . . . . . . . 76

6 Adding New Features 77

6.1 Scenario Outlines in Cucumber . . . . . . . . . . . . 77

6.2 Responding to Change . . . . . . . . . . . . . . . . . 80

6.3 What We’ve Learned . . . . . . . . . . . . . . . . . . . 83

7 Specifying an Algorithm 84

7.1 Begin with the Simplest Example . . . . . . . . . . . 84

7.2 Refactor to Remove Duplication . . . . . . . . . . . . 88

7.3 Refactor to Express Intent . . . . . . . . . . . . . . . 89

7.4 What We’ve Learned . . . . . . . . . . . . . . . . . . . 94

8 Refactoring with Confidence 96

8.1 Sniffing Out Code Smells . . . . . . . . . . . . . . . . 96

8.2 One Step at a Time . . . . . . . . . . . . . . . . . . . 98

8.3 Updating Specs After Refactoring . . . . . . . . . . . 107

8.4 Exploratory Testing . . . . . . . . . . . . . . . . . . . 111

8.5 What We’ve Learned . . . . . . . . . . . . . . . . . . . 112

9 Feeding Back What We’ve Learned 114

9.1 Use Cucumber for Collaboration . . . . . . . . . . . 114

9.2 Experimenting with a New Implementation . . . . . 118

9.3 What We’ve Learned . . . . . . . . . . . . . . . . . . . 122

Report erratum

this copy is (P1.0 printing, December 2010) Download from Wow! eBook <www.wowebook.com>

www.it-ebooks.info

CONTENTS 7

II Behaviour-Driven Development 124

10 The Case for BDD 125

10.1 How Traditional Projects Fail . . . . . . . . . . . . . 125

10.2 Why Traditional Projects Fail . . . . . . . . . . . . . 126

10.3 Redefining the Problem . . . . . . . . . . . . . . . . . 130

10.4 The Cost of Going Agile . . . . . . . . . . . . . . . . . 133

10.5 What We’ve Learned . . . . . . . . . . . . . . . . . . . 136

11 Writing Software That Matters 138

11.1 A Description of BDD . . . . . . . . . . . . . . . . . . 138

11.2 The Principles of BDD . . . . . . . . . . . . . . . . . 138

11.3 The Project Inception . . . . . . . . . . . . . . . . . . 139

11.4 The Cycle of Delivery . . . . . . . . . . . . . . . . . . 141

11.5 What’s in a Story? . . . . . . . . . . . . . . . . . . . . 145

11.6 What We’ve Learned . . . . . . . . . . . . . . . . . . . 148

III RSpec 149

12 Code Examples 150

12.1 Describe It! . . . . . . . . . . . . . . . . . . . . . . . . 151

12.2 Pending Examples . . . . . . . . . . . . . . . . . . . . 155

12.3 Hooks: Before, After, and Around . . . . . . . . . . . 158

12.4 Helper Methods . . . . . . . . . . . . . . . . . . . . . 162

12.5 Shared Examples . . . . . . . . . . . . . . . . . . . . 164

12.6 Nested Example Groups . . . . . . . . . . . . . . . . 166

12.7 What We’ve Learned . . . . . . . . . . . . . . . . . . . 169

13 RSpec::Expectations 170

13.1 should, should_not, and matchers . . . . . . . . . . 171

13.2 Built-in Matchers . . . . . . . . . . . . . . . . . . . . 172

13.3 Predicate Matchers . . . . . . . . . . . . . . . . . . . 180

13.4 Be True in the Eyes of Ruby . . . . . . . . . . . . . . 181

13.5 Have Whatever You Like . . . . . . . . . . . . . . . . 182

13.6 Operator Expressions . . . . . . . . . . . . . . . . . . 186

13.7 Generated Descriptions . . . . . . . . . . . . . . . . . 187

13.8 Subjectivity . . . . . . . . . . . . . . . . . . . . . . . . 188

13.9 What We’ve Learned . . . . . . . . . . . . . . . . . . . 190

Report erratum

this copy is (P1.0 printing, December 2010) Download from Wow! eBook <www.wowebook.com>

www.it-ebooks.info

CONTENTS 8

14 RSpec::Mocks 191

14.1 Test Doubles . . . . . . . . . . . . . . . . . . . . . . . 192

14.2 Method Stubs . . . . . . . . . . . . . . . . . . . . . . 193

14.3 Message Expectations . . . . . . . . . . . . . . . . . 195

14.4 Test-Specific Extensions . . . . . . . . . . . . . . . . 197

14.5 More on Method Stubs . . . . . . . . . . . . . . . . . 201

14.6 More on Message Expectations . . . . . . . . . . . . 203

14.7 When to Use Test Doubles and Test-Specific Exten￾sions . . . . . . . . . . . . . . . . . . . . . . . . . . . 213

14.8 Risks and Trade-Offs . . . . . . . . . . . . . . . . . . 218

14.9 Choosing Other Test Double Frameworks . . . . . . 220

14.10 What We’ve Learned . . . . . . . . . . . . . . . . . . . 222

15 Tools and Integration 224

15.1 The rspec Command . . . . . . . . . . . . . . . . . . 224

15.2 TextMate . . . . . . . . . . . . . . . . . . . . . . . . . 229

15.3 Autotest . . . . . . . . . . . . . . . . . . . . . . . . . . 230

15.4 Rake . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230

15.5 RCov . . . . . . . . . . . . . . . . . . . . . . . . . . . 232

15.6 What We’ve Learned . . . . . . . . . . . . . . . . . . . 233

16 Extending RSpec 234

16.1 Metadata . . . . . . . . . . . . . . . . . . . . . . . . . 234

16.2 Configuration . . . . . . . . . . . . . . . . . . . . . . 235

16.3 Filtering . . . . . . . . . . . . . . . . . . . . . . . . . . 235

16.4 Extension Modules . . . . . . . . . . . . . . . . . . . 238

16.5 Global Hooks . . . . . . . . . . . . . . . . . . . . . . . 239

16.6 Mock Framework . . . . . . . . . . . . . . . . . . . . 239

16.7 Custom Matchers . . . . . . . . . . . . . . . . . . . . 240

16.8 Macros . . . . . . . . . . . . . . . . . . . . . . . . . . 244

16.9 Custom Formatters . . . . . . . . . . . . . . . . . . . 247

16.10 What We’ve Learned . . . . . . . . . . . . . . . . . . . 250

IV Cucumber 251

17 Intro to Cucumber 252

17.1 From 20,000 Feet . . . . . . . . . . . . . . . . . . . . 253

17.2 Features . . . . . . . . . . . . . . . . . . . . . . . . . 253

17.3 Customer Acceptance Tests . . . . . . . . . . . . . . 257

17.4 Gherkin . . . . . . . . . . . . . . . . . . . . . . . . . . 257

17.5 Scenarios . . . . . . . . . . . . . . . . . . . . . . . . . 259

Report erratum

this copy is (P1.0 printing, December 2010) Download from Wow! eBook <www.wowebook.com>

www.it-ebooks.info

CONTENTS 9

17.6 Steps . . . . . . . . . . . . . . . . . . . . . . . . . . . 260

17.7 The cucumber Command . . . . . . . . . . . . . . . 261

17.8 Given/When/Then . . . . . . . . . . . . . . . . . . . 262

17.9 Declarative and Imperative Scenario Styles . . . . . 263

17.10 Organizing Features . . . . . . . . . . . . . . . . . . 264

17.11 Tags . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265

17.12 What We’ve Learned . . . . . . . . . . . . . . . . . . . 267

18 Cucumber Detail 269

18.1 Step Definitions . . . . . . . . . . . . . . . . . . . . . 269

18.2 World . . . . . . . . . . . . . . . . . . . . . . . . . . . 271

18.3 Calling Steps Within Step Definitions . . . . . . . . 272

18.4 Hooks . . . . . . . . . . . . . . . . . . . . . . . . . . . 273

18.5 Background . . . . . . . . . . . . . . . . . . . . . . . 275

18.6 Multiline Text . . . . . . . . . . . . . . . . . . . . . . 276

18.7 Tables in Steps . . . . . . . . . . . . . . . . . . . . . 277

18.8 Scenario Outlines . . . . . . . . . . . . . . . . . . . . 278

18.9 Configuration . . . . . . . . . . . . . . . . . . . . . . 280

18.10 What We’ve Learned . . . . . . . . . . . . . . . . . . . 280

V Behaviour-Driven Rails 282

19 BDD in Rails 283

19.1 Outside-In Rails Development . . . . . . . . . . . . . 284

19.2 Setting Up a Rails 3 Project . . . . . . . . . . . . . . 286

19.3 Setting Up a Rails 2 Project . . . . . . . . . . . . . . 289

19.4 What We’ve Learned . . . . . . . . . . . . . . . . . . . 289

20 Cucumber with Rails 290

20.1 Step Definition Styles . . . . . . . . . . . . . . . . . . 290

20.2 Direct Model Access . . . . . . . . . . . . . . . . . . . 292

20.3 What We’ve Learned . . . . . . . . . . . . . . . . . . . 297

21 Simulating the Browser with Webrat 298

21.1 Writing Simulated Browser Step Definitions . . . . . 299

21.2 Navigating to Pages . . . . . . . . . . . . . . . . . . . 304

21.3 Manipulating Forms . . . . . . . . . . . . . . . . . . 308

21.4 Specifying Outcomes with View Matchers . . . . . . 313

21.5 Building on the Basics . . . . . . . . . . . . . . . . . 316

21.6 What We’ve Learned . . . . . . . . . . . . . . . . . . . 319

Report erratum

this copy is (P1.0 printing, December 2010) Download from Wow! eBook <www.wowebook.com>

www.it-ebooks.info

CONTENTS 10

22 Automating the Browser with Webrat and Selenium 320

22.1 Getting Started . . . . . . . . . . . . . . . . . . . . . 321

22.2 Writing Step Definitions for Selenium . . . . . . . . 324

22.3 Debugging Selenium Issues . . . . . . . . . . . . . . 328

22.4 What We’ve Learned . . . . . . . . . . . . . . . . . . . 330

23 Rails Views 331

23.1 Writing View Specs . . . . . . . . . . . . . . . . . . . 331

23.2 Mocking Models . . . . . . . . . . . . . . . . . . . . . 334

23.3 Specifying Helpers . . . . . . . . . . . . . . . . . . . . 341

23.4 When Should I Write View Specs? . . . . . . . . . . . 343

23.5 What We’ve Learned . . . . . . . . . . . . . . . . . . . 343

24 Rails Controllers 345

24.1 Controller Specs . . . . . . . . . . . . . . . . . . . . . 345

24.2 Context-Specific Examples . . . . . . . . . . . . . . . 352

24.3 Specifying ApplicationController . . . . . . . . . . . 361

24.4 What We’ve Learned . . . . . . . . . . . . . . . . . . . 363

25 Rails Models 365

25.1 Writing Model Specs . . . . . . . . . . . . . . . . . . 365

25.2 Specifying Business Rules . . . . . . . . . . . . . . . 373

25.3 Exercise . . . . . . . . . . . . . . . . . . . . . . . . . . 382

25.4 Useful Tidbits . . . . . . . . . . . . . . . . . . . . . . 383

25.5 What We’ve Learned . . . . . . . . . . . . . . . . . . . 386

A RubySpec 388

A.1 The Project . . . . . . . . . . . . . . . . . . . . . . . . 389

A.2 Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . 389

A.3 Guards . . . . . . . . . . . . . . . . . . . . . . . . . . 391

A.4 Extensibility . . . . . . . . . . . . . . . . . . . . . . . 392

A.5 MSpec . . . . . . . . . . . . . . . . . . . . . . . . . . . 394

A.6 Tags . . . . . . . . . . . . . . . . . . . . . . . . . . . . 394

A.7 Community . . . . . . . . . . . . . . . . . . . . . . . . 395

B RSpec’s Built-in Expectations 397

C Bibliography 401

Index 403

Report erratum

this copy is (P1.0 printing, December 2010) Download from Wow! eBook <www.wowebook.com>

www.it-ebooks.info

Foreword

Caution! You’ve fallen for a trap. You’ve picked up this book thinking it

was about RSpec. Fortunately, you decided to read the foreword. Good!

That gives me the opportunity to tell you about the mistake you just

made and possibly save you from an unexpected fate.

You see, this book isn’t about RSpec at all. Oh, RSpec is certainly men￾tioned. There are lots of examples of how to use it. There’s even a very

detailed reference manual in Part III. But that’s all just part of an insid￾iously clever deception, because this book is not about RSpec.

Perhaps you thought you might read about Cucumber? After all, Part

IV is named “Cucumber.” Oh, these authors are clever; God they are!

They’ve littered this book with examples and details that tell you all

about Cucumber in all its intricacies and all its copious fiddledy-bits.

There’s even a section on using it with Rails and Webrat and all the

other gory things that you’ll need to become a Cucumber expert. But

this book is not about Cucumber.

No. This book is not about RSpec. And this book is not about Cucum￾ber. This book is about. . .

I’m not sure I should tell you. I mean, once the secret gets out, it’s liable

to cause mayhem. If it ever got out who the audience for this book really

is, if the masses learned of the diabolical plan being executed in their

midst, I’m not sure our civilization would survive.

You see. . . (come closer, and cover this part with your hand so nobody

else can see it). . . you see, this book is not for. . . (covered?). . . it’s not for

Ruby programmers!

There, I’ve said it! Now don’t panic, and don’t drop the book—whatever

you do, don’t drop the book! Hold on tight, and keep it covered. Don’t

let anyone else see.

Download from Wow! eBook <www.wowebook.com>

www.it-ebooks.info

FOREWORD 12

Yes, you see, this book is not about RSpec. It’s not about Cucumber, It’s

not for Ruby programmers. This book is for. . . (covered again?). . . it’s for

all programmers!

Keep a good tight grip. I know it’s hard. Don’t look around suspiciously.

Don’t draw attention to yourself. Just try to stay calm, breathe nor￾mally, and keep reading.

Yes, all the code is in Ruby. Yes, all the examples use RSpec and

Cucumber to one degree or another. Yes, if you read this book, you will

learn RSpec, Cucumber, and things about Ruby and Rails and Webrat

that you didn’t know before. No doubt about it. Remember, the best lies

are near-truths.

Here’s the thing. While you read this book, you will think you are

learning about all those cool tools. You will think “Oh, cool, I’m learn￾ing RSpec and Cucumber.” But you will be learning something else at

the same time! Something unexpected. Something unadvertised. Some￾thing, perhaps, unwelcome.

As you read these pages, a hidden meme will creep into your mind—a

meme of such potency and power that it is likely to change everything

about the way you program. And not just how you program in Ruby!

If you read this book, that meme will change the way you program

in Java, C#, Python, or (oh, God, the thought) COBOL! This book will

change the way you code—period!

Worse, you don’t have to be a Ruby programmer to be infected by this

meme. As I said, these authors are clever. Their unholy plan is to infect

all programmers with this meme. You see, they’ve cleverly constructed

the Ruby code in this book so that it can be understood by (gasp) any

programmer at all! I mean, this is worse than Fluoridation!

Any programmer who picks up this book will be infected by the meme.

And the meme is subtle. And the meme is persistent. And the meme

will have its way. And when it does, our industry will never be the same

again. Are you willing to risk that?

What is this meme? What name shall we give it? The meme is legion!

It’s not just Agile, though Agile is there. It’s not just TDD and BDD,

though both are there. It’s not just Continuous Integration, Accep￾tance Test–Driven Development, Acceptance Test–Driven Planning, or

even Extreme Programming, though all those things are present in the

meme.

Report erratum

this copy is (P1.0 printing, December 2010) Download from Wow! eBook <www.wowebook.com>

www.it-ebooks.info

FOREWORD 13

No, the meme is more than any one of those things. The meme is a

synergistic witches brew of some of the most contagious and effective

ideas of the past two decades. The meme is. . .

Dare I say it?

The meme is. . .

. . . Craftsmanship.

—Robert C. Martin

Report erratum

this copy is (P1.0 printing, December 2010) Download from Wow! eBook <www.wowebook.com>

www.it-ebooks.info

About the Authors

David Chelimsky is the lead developer/maintainer of RSpec, and has

contributed to several other open source projects including Cucumber,

Aruba, and Rails. He has been developing software for over a decade,

including three years training and mentoring agile teams at Object

Mentor. He is currently a Senior Software Engineer at DRW Trading

Group in Chicago, IL. In his spare time, David likes to play guitar,

travel, and speak something resembling Portuguese.

Dave Astels is the Director of Technology at ChannelFireball.com and

has been involved with software and computing for over 25 years,

recently having spent several years working exclusively with Ruby and

Rails. Dave wrote the article that prompted Steven Baker to start the

RSpec project.

Zach Dennis is a co-founder and fellow human at Mutually Human

Software, an expert custom software strategy and design consultancy

in Grand Rapids, Michigan. He has been enjoying Ruby for nearly eight

years and has contributed to several projects such as Ruby’s standard

library documentation, Ruby on Rails, and RSpec. In his spare time,

Zach loves spending time with his family, continuously learning, play￾ing music, and running continuousthinking.com.

Aslak Hellesøy is a Senior Software Engineer at DRW Trading Group

in London. While contributing to this book he was the Chief Scientist

of BEKK Consulting in Oslo. In 2003, after seven years of professional

Java programming, he fell in love with Ruby. He has contributed to

dozens of open source projects and is the founder of the Cucumber

project. Aslak likes to cook, ski, and travel.

Bryan Helmkamp maintains Webrat, a Ruby library to implement ac￾ceptance tests for web applications in an expressive and maintainable

way, and is an active participant in the New York City Ruby commu￾nity. Bryan is the CTO of Efficiency 2.0, a startup that helps people

understand and reduce their energy use.

Download from Wow! eBook <www.wowebook.com>

www.it-ebooks.info

ABOUT THE AUTHORS 15

Dan North writes software and coaches teams and organizations in

agile and lean methods. He believes that most problems that teams face

are about communication and understanding, which is why he puts so

much emphasis on “getting the words right.” In 2003–4 this led him to

develop the ideas that would become Behaviour-Driven Development.

He is delighted by the community that has grown up around RSpec

and Cucumber, and especially the enthusiasm and dedication of their

core contributors. Dan is currently a Senior Software Engineer at DRW

Trading Group in London, where he gets to actually code again!

Report erratum

this copy is (P1.0 printing, December 2010) Download from Wow! eBook <www.wowebook.com>

www.it-ebooks.info

Tải ngay đi em, còn do dự, trời tối mất!