In this chapter, we'll see how YII2 helps us create web apps. Although the example is simple, the whole process conforms to the software engineering idea. We will complete every step of application development, and each step will be based on best practices in the authoritative book:
Create a domain model: This book explains the field drive, tackling complexity in the heart of software, Eric Evans, Addison-wesley Professional
Set up test devices: We follow the acceptance test drive practice, growing object-oriented software, Guided by Tests, Steve Freeman and Nat Pryce, Addison-wesley profess ional
Set up the development pipeline
Continuous delivery: Reliable software releases through Build, Test, and Deployment Automation, Jez Humble and David Farley, Addison-wesle Y Professional
Continuous integration: Improving software quality and reducing Risk, Paul M. Duvall, Steve Matyas, and Andrew Glover, Addison-wesley profess ional
Red-green-refactoring development cycle: in-depth explanations, please refer to the following books:
Clean CODE:A Handbook of Agile software craftsmanship, Robert Martin, Prentice Hall
Test-driven development by Example, Kent Beck, Addison-wesley Professional
Deployment and Manual testing: This is consistent with continuous delivery, and these steps are also essential
Stay focused.
Design phase
Throughout the book, we need to be aware of the actual requirements when using the sample application. In this section, we will define the scenario for the entire example.
Task
Suppose we have a small business application that wants to provide some service to the outside. We have some clients, and they have a huge number of accounts on paper that are very inconvenient to manage with business cards. Therefore, we need to manage these files in an automated way.
First of all, we need some additions and deletions (CRUD) interface for records management, to show customers the most core attributes.
Clearly, our business and our customers may grow and change over time, so our applications should change as well. At the outset, we should be prepared for possible changes.
In the spirit of eating their own dog food principles (The Microsoft in 1998), since the development of their own system to use, the system is best guaranteed to be high-quality.
Domain Model design
Obviously, we'll work with the customer model in the app. In the "Customer" and "client" two words, we feel that "customer" is more appropriate.
A customer is a person who has at least attributes such as name, address, e-mail, and phone number. We provide a service for our customers, hourly, and pay for this period of time according to the contract. This is the problem we intend to solve in our first iteration design .
We assume that each customer is a single person, so we don't have to deal with the company, there are multiple contacts in the case. Name is a complex structure, if we go into detail, there are honorific, title, nickname, middle name, surname and other attributes need to be considered. But in this application, we are not really interested in the name of the customer, we just need to use the name to identify a customer. Therefore, we will simply use a line of text to represent, allowing us to write names in any format. The address can also be a complex structure, and this time we're going to use a structure to describe it instead of a simple line of text. This is because we need addresses to achieve the following two things.
Make some statistics, such as how many customers in a particular city
Follow different cultural backgrounds to generate mailing addresses correctly
Therefore, we decided to use the following structure:
Use (ex: billing address, shopping address, home address, work address)
Countries
A region of lower state, such as the United States.
City
Street
Buildings
Department/Office
Recipient's name
Zip code
We should note that an address can represent a department, a mailbox, an office, an employee in an organization, or even an entire building. Similarly, a customer can have multiple addresses.
Phone This entity has the following properties:
Use (personal or work)
Number
A customer may have several phone numbers that are differentiated by use fields.
In addition to the entity of name, address and telephone, our staff need a way to describe the customer freely. Here we simplify the name attribute. Then, we add birthdays, email attributes, and of course, a customer can have multiple emails.
Let's stop for a second.
We can now draw a complete aggregation diagram of the customer model, as shown in:
According to Eric Evans's domain-driven design, the customer is an entity, that is, an object whose state can be changed, so we need to be concerned about its consistency throughout the system. The other part is the value object, which means that after the initial creation, the state does not change the object, so they can be completely interchangeable.
In order to simplify processing, we no longer describe in detail how the customer is handled by the business, and we do not intend to cover it in this book. In any case, let's take our attention back to the range of services we provide to our customers, and it will be useful to maintain these records. We will use this model in later chapters.
Target characteristics
Let's do a specific task. Considering that some people call us (if we have identified the number), we want to get all the details of the incoming caller. in the application, if the number does not find the associated person, then we know that he is not our client. If we find an affiliate, we can at least greet him directly with his name, which is a good customer service.
We should understand database queries, we need a way to insert data, and it is possible to edit and delete it. Therefore, the features of our first iteration of development include the following:
Inserting customer information into a database
Edit customer information in the database
Delete Customer information from the database
Query customer information from a database by phone number
Constructing a generic database query is not our goal, we just need to query based on a phone number.
Let's get started.
Initial preparation
Until the end of the book, we'll discuss the same application in the next chapters, so the preparation will only need to do this once.
Download sample code: Packt's website can download the sample code you purchased the book, the address is http://www.packtpub.com, if you have purchased this book, please visit Http://www.packtpub.com/support, After registering, the file will be emailed to you directly.
Configure Project Management
The application that we want to develop, essentially, is a customer relationship management system (CRM). Therefore, we first create a directory named Crmapp.
Note that in the original book, the example that is invoked through the command line assumes that your current directory is the Crmapp directory.
YII2 recommends using Package Manager composer for installation, so we'll use this tool. You can read composer's full documentation for detailed details, and we've prepared a short description here :
All packages installed through composer will be stored under the project path, in a subdirectory named vendor.
Composer-related data, all dependencies and other information, are stored in a manifest file named Composer.json, located at the root of the project. As long as you declare the dependency in this file, you can safely delete the vendor directory at any time and completely rebuild when you call PHP Composer.phar Install or PHP composer.phar update.
Composer's documentation describes a way to get Composer.phar:
Curl-ss Https://getcomposer.org/installer | Php
Of course, if you do not have curl in your path path, you can also go directly to composer's official website https://getcomposer.org/Download the Phar file directly. (Note: If it is a Windows environment, it is recommended to download a composer installation package directly, after the installation is completed, add to the path directory, you can use the composer <command> to make the call, instead of using PHP Composer.phar <command>, more convenient).
Once we are ready, we can execute the command in the following format:
PHP Composer.phar <command>
Assuming you use a version control system to manage your code, this book's code is managed using Git (http://git-scm.com/).
Quick guidance in the preparation phase:
mkdir CRMAPPCD Crmappcurl-ss | Phpgit Init
Configuring the Test Tool
As we said at the beginning of this chapter, we will follow test-first development practices for acceptance testing. This is done for the following reasons:
We want to check if the app works and don't want to use tedious manual testing
We do not have the deep unit testing requirements, because our main task now is to assemble the existing components together, so it is easiest and feasible to perform end-to-end acceptance testing of the UI
If we care about the implementation of the user feature request, we need some form of acceptance testing.
Yii2 built-in support codeception test framework, the official site is http://codeception.com/. We won't use it directly in ourselves, but Yii2-codeception (https://github.com/yiisoft/yii2-codeception) provides some helper classes to integrate into the YII framework.
Let's make it clear that we need to use codeception in the project to execute the following command:
PHP Composer.phar require "codeception/codeception:*"
Wait a moment until the composer execution is complete.
Currently, the contents of the Composer.json file are:
{"Require": {"codeception/codeception": "*",}}
Command PHP Composer.phar require < package name: Version > is just an auxiliary method, insert the require block into the manifest file, and invoke the update command.
Of course, I also need to add Yii2 as a dependency, but before that, let's do one thing first.
As we can see, codeception already exists in the./vendor/bin/codecept directory. This path is long, and in a POSIX-compatible shell, like bash, allows us to simplify it in the following ways:
Alias cept= "./vender/bin/codecept"
That would be better. In the remainder of this chapter, we assume that you have executed the above command.
Codeception is a complex system, so we need to rely on its own built-in commands. There is no need to delve into the internal details of codeception, we are just simple and practical. Execute the following command:
Cept Bootstrap
This will generate a tests directory for codeception and configure it.
Now, let's create a fool-type acceptance test to check our testing tools.
Cept generate:cept Acceptance SmokeTest
This command will generate smoketestcept.php, located in the Tests/acceptance directory. When we open this file, we will see the following code (depending on the codeception version, the code may be slightly different):
$I = new Acceptancetester ($scenario); $I->wantto (' Perform actions and see result ');
Acceptancetester is a class that can mimic a browser's real users and test the application. Codeception also provides codeguy for unit testing and provides testguy for functional testing, which we will use later.
When we call Acceptancetester.wantto ("do something"), we just create a caption (enclosed in double quotes) for the following test behavior.
Let's change the code, add the Smoke test feature, and test our home page:
$I = new Acceptancetester ($scenario), $I->wantto (' See, landing page is up '), $I->amonpage ('/'); $I->see (' Our CRM ');
When we visit the application homepage, we want to see our CRM line. Suppose we already have a title in our application.
Now run the test:
Cept Run
We will see the failed message because we have not set up the Web server, processing/request. So, it's time for us to write some production code to pass this test. However, for now, what we need is not production code, and our basic services have not yet been built up. We need to establish a release mechanism first.
Configure the release pipeline
As we've already said, the Web acceptance tests you write simulate real users, open the app in a browser, and interact with the visual UI. So what we need to do now is to deploy the entire application to the machines where we can run the acceptance tests.
Tip: The most common scenario is that you decide to develop and test using the same machine, which is wrong! Don't do this.
It is likely that your work platform is not the same machine that the application will eventually run. This is an ongoing problem, referring to the decades-old industrial production. When the life cycle of an application is expected to be years, test your application on a production server in a different environment and you will face similar integration problems. Of course, this is not to sell packaged software to the user, this is still easier. In our case, we assume that a single publishing point has only one fixed web application, so simplicity is not an issue, and repeatable testing is the problem.
In the end, your acceptance test will contain the following steps:
Of course, you can run the acceptance test on the test server. To do this, you only need to configure the test with localhost, the local Loop network interface. However, you still need to install some software that is irrelevant to the test server. For example, if you want to run a full stack, use selenium for in-browser testing, you may need to install a Web browser, Java runtime, virtual framebuffer software, and this requires the installation of their respective software, which is very laborious. The most efficient way to run web acceptance tests is to use your own desktop environment.
Tip: This is certainly not about unit testing and functional testing. Unit tests, which are only related to itself, should be executed where there is the original code, without the need for deployment at all. Functional testing should be tested on post-deployment applications because of the need to test the configured final application and the correctness of the interaction.
In any case, the idealized scenario is that you just need a simple command like deploy to do the following:
Access and start the target machine (especially when it is a virtual machine instance)
Ensure that the environment is effective in addition to the application
Copy the current code to the target machine
On the target machine, configure the environment where the past code has just been copied
Launch the App
You should be able to enter deploy on the command line and hit the ENTER key to complete all of the above steps. As Martin Fowler in his "Continuous Integration" (http://martinfowler.com/articles/continuousIntegration.html), this is a piece of cake for you. Ideally, the deployment behavior should be done automatically when you start the acceptance testing tool.
In this book, we are only concerned with the last two steps. Since we are developing PHP applications, the "Launch application" step is complete, as long as the Web server on the target machine is running.
This book focuses only on Web application development and does not involve system administration, which is a matter for the system administrator. However, in Appendix A, "Deployment settings using vagrant", we are ready to introduce a virtual machine-based deployment that is also easy to implement on any desktop workstation. You can still simulate the real-world deployment process without needing another physical machine. If you have no choice, you are strongly recommended to read. In fact, with the description there, all of the code itself is ready. Let's assume that you have a prepared environment and deploy command, for simplicity, we also assume that the deployment will run automatically each time the acceptance test is run. The results of the deployment can be accessed from your machine via a simple URL, and the Acceptance test tool will use it as an entry point for your application.
Now, let's go to Codeception's configuration section related to the acceptance test, open the file tests/acceptance.suite.yml, and add the entry URL to the Modules.config.PhpBrowser.url entry. Assuming you haven't modified the file, the contents of the file should look like this:
class_name:AcceptanceTestermodules:enabled:-Phpbrowser-webhelper Config:phpbrowser: URL: ' Http://YOUR.APPLICATION.URL '
(Note: The native acceptance.suite.yml file format is different from the above, there is no config entry, the URL is placed directly under the enabled Phpbrowser)
For example, if you use Apache's IP-based virtual host technology to configure the target machine (https://httpd.apache.org/docs/2.2/vhosts/ ip-based.html), the value of Modules.config.PhpBrowser.url should look like this: http://127.0.0.01:8000.
When we change the configuration, we need to rebuild the codeception and execute the following command:
CEPT Build
Don't forget cept This alias was created by ourselves. The./vendor/bin/codecept file is actually running.
If you run the test now:
Cept Run
You should be able to see the following output:
You'll see that codeception on/route shows something, but it's not what we're looking for. Depending on the version of Apache used, it can be either a 404 error or a 403 error. If you are using another Web server, additional error messages may be displayed. Anyway, the root of the problem is simple: we need to add the index.php file to a web directory that is accessible to the outside world.
Create a visible web App portal
We first make a convention, can be accessed by the external directory only one, named the Web, placed in the root directory of the project. For example, if your Web server is Apache, you should point DocumentRoot to the Web directory.
Therefore, place the following content in the index.php file of the Web directory:
Our CRM
Yes, it is a 7-character text file. After all, is this what we expect from the acceptance test, right?
Let's run the test:
Cept Run
We have the following output:
Now that we need to use YII2 in our project, the best way to describe our functional requirements is to write a complete end-to-end test.
"Translation" Yii2 2nd create custom Apps with Yii2 (section 1th)