8000 Add acceptance testing barebones. · pwalen/testing-python-apps@9387bfa · GitHub
[go: up one dir, main page]

Skip to content
Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 9387bfa

Browse files
committed
Add acceptance testing barebones.
1 parent ac77623 commit 9387bfa

20 files changed

+243
-3
lines changed

section6/video_code/README.md

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
# Set up
2+
3+
We'll need a few things to install for this section:
4+
5+
- https://sites.google.com/a/chromium.org/chromedriver/downloads
6+
- behave (http://pythonhosted.org/behave/)
7+
- selenium (http://selenium-python.readthedocs.io/installation.html)
8+
9+
10+
## Running the tests
11+
12+
To run the tests, you'll need to do this in a terminal (but remember to have the Flask app running!):
13+
14+
```bash
15+
source venv/bin/activate
16+
cd section6/video_code/
17+
python -m behave tests/acceptance
18+
```
19+
20+
If you want to run the tests in PyCharm, you'll need to create appropriate configurations.
21+
22+
Create a Python configuration for the app.
23+
24+
[]
25+
26+
Create a Python configuration for the running of behave tests.
27+
28+
[]

section6/video_code/app.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
from flask import Flask, render_template, request, redirect, url_for
2+
3+
app = Flask(__name__)
4+
5+
posts = []
6+
7+
8+
@app.route('/')
9+
def homepage():
10+
return render_template('home.html')
11+
12+
13+
@app.route('/blog')
14+
def blog_page():
15+
return render_template('blog.html', posts=posts)
16+
17+
18+
@app.route('/post', methods=['GET', 'POST'])
19+
def add_post():
20+
if request.method == 'POST':
21+
title = request.form['title']
22+
content = request.form['content']
23+
global posts
24+
25+
posts.append({
26+
'title': title,
27+
'content': content
28+
})
29+
30+
return redirect(url_for('blog_page'))
31+
return render_template('new_post.html')
32+
33+
34+
@app.route('/post/<string:title>')
35+
def see_post(title):
36+
global posts
37+
38+
for post in posts:
39+
if post['title'] == title:
40+
return render_template('post.html', post=post)
41+
42+
return render_template('post.html', post=None)
43+
44+
45+
if __name__ == '__main__':
46+
app.run()

section6/video_code/requirements.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Flask
2+
uwsgi
3+
behave==1.2.5
4+
beautifulsoup4==4.5.3
5+
selenium==3.4.1
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
5+
</head>
6+
<body>
7+
<h1>This is the blog page</h1>
8+
9+
<a href="{{ url_for('homepage') }}" class="nav-link" id="home-link">Go to home</a>
10+
<a href="{{ url_for('add_post') }}" class="nav-link" id="add-post-link">Create post</a>
11+
12+
{% if posts|length > 0 %}
13+
<ol>
14+
{% for post in posts %}
15+
<li><a href="{{ url_for('see_post', title=post['title']) }}">{{ post['title'] }}</a></li>
16+
{% endfor %}
17+
</ol>
18+
{% endif %}
19+
</body>
20+
</html>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
5+
</head>
6+
<body>
7+
<h1>This is the homepage</h1>
8+
9+
<a href="{{ url_for('blog_page') }}" class="nav-link" id="blog-link">Go to blog</a>
10+
</body>
11+
</html>
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
5+
</head>
6+
<body>
7+
<h1>Create post</h1>
8+
9+
<a href="{{ url_for('blog_page') }}" class="nav-link" id="blog-link">Back to blog</a>
10+
11+
<form method="POST">
12+
<div>
13+
<label for="title">Post title:</label>
14+
<input type="text" name="title" id="title" />
15+
</div>
16+
<div>
17+
<label for="content">Post content:</label>
18+
<textarea name="content" id="content"></textarea>
19+
</div>
20+
<div>
21+
<button type="submit" id="create-post">Create</button>
22+
</div>
23+
</form>
24+
</body>
25+
</html>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
5+
</head>
6+
<body>
7+
{% if post %}
8+
<h1>{{ post['title'] }}</h1>
9+
10+
<p>{{ post['content'] }}</p>
11+
{% else %}
12+
<h1>Post not found!</h1>
13+
{% endif %}
14+
</body>
15+
</html& F438 gt;

section6/video_code/tests/__init__.py

Whitespace-only changes.

section6/video_code/tests/acceptance/__init__.py

Whitespace-only changes.

section6/video_code/tests/acceptance/pages/__init__.py

Whitespace-only changes.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
class BasePage:
2+
pass
3+
4+
5+
class BaseLocators:
6+
pass
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from section6.video_code.tests.acceptance.pages.base_page import BasePage
2+
3+
4+
class BlogPage(BasePage):
5+
pass
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from section6.video_code.tests.acceptance.pages.base_page import BasePage
2+
3+
4+
class HomePage(BasePage):
5+
pass
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from section6.video_code.tests.acceptance.pages.base_page import BasePage
2+
3+
4+
class NewPostPage(BasePage):
5+
pass
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from section6.video_code.tests.acceptance.pages.base_page import BasePage
2+
3+
4+
class PostPage(BasePage):
5+
pass

section6/video_code/tests/acceptance/steps/__init__.py

Whitespace-only changes.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from behave import *
2+
from selenium.webdriver.common.by import By
3+
4+
use_step_matcher('re')
5+
6+
7+
@then('There is a (.*) tag with the content "(.*)"')
8+
def step_impl(context, tag_name, tag_content):
9+
tag = context.browser.find_element(By.XPATH, '//{}[text()="{}"]'.format(tag_name, tag_content))
10+
assert tag is not None
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
from behave import *
2+
from selenium import webdriver
3+
4+
use_step_matcher('re')
5+
6+
7+
@given('I am on the homepage')
8+
def step_impl(context):
9+
context.browser = webdriver.Chrome()
10+
context.browser.get('http://127.0.0.1:5000/')
11+
12+
13+
@given('I am on the blog page')
14+
def step_impl(context):
15+
context.browser = webdriver.Chrome()
16+
context.browser.get('http://127.0.0.1:5000/blog')
17+
18+
19+
@when('I click on the link with id "(.*)"')
20+
def step_impl(context, link_id):
21+
link = context.browser.find_element_by_id(link_id) # find_element_by_link_text can also work
22+
link.click()
23+
24+
25+
@then('I am on the homepage')
26+
def step_impl(context):
27+
assert context.browser.current_url == 'http://127.0.0.1:5000/'
28+
29+
30+
@then('I am on the blog page')
31+
def step_impl(context):
32+
assert context.browser.current_url == 'http://127.0.0.1:5000/blog'
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
Feature: Test navigation between pages
2+
Make sure homepage can go to blog, and
3+
blog can go to homepage
4+
5+
Scenario: Homepage can go to Blog
6+
Given I am on the homepage
7+
When I click on the link with id "blog-link"
8+
Then I am on the blog page
9+
10+
Scenario: Blog page can go to homepage
11+
Given I am on the blog page
12+
When I click on the link with id "home-link"
13+
Then I am on the homepage
14+
15+
Scenario: Blog page has an appropriate title
16+
Given I am on the blog page
17+
Then There is a h1 tag with the content "This is the blog page"
18+
19+
Scenario: Homepage has an appropriate title
20+
Given I am on the homepage
21+
Then There is a h1 tag with the content "This is the homepage"

testing-python-apps.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010

1111
- Travis CI is set up only for Section 2.
1212

13+
https://docs.travis-ci.com/user/languages/python/
14+
1315
### Section 3: Integration testing
1416

1517
### Sections 4 + 5: System testing
@@ -21,9 +23,8 @@
2123
Remember to cover installing the necessary PyCharm plugins to be able to run things
2224
simultaneously. Need:
2325

24-
25-
- Multirun
26-
- BashSupport (or CMDSupport on Windows)
26+
- `Multirun`, to allow to run multiple configurations in parallel.
27+
- `BashSupport` (or `CMDSupport` on Windows), to allow running command-line scripts.
2728
- Also need to check how to do this on Windows
2829

2930
### Section 6: Acceptance testing

0 commit comments

Comments
 (0)
0