【问题标题】:Coverage.py ignores importing and class definition codeCoverage.py 忽略导入和类定义代码
【发布时间】:2017-09-28 07:23:03
【问题描述】:

我正在使用 coverage.py 对我的 Flask 应用程序进行单元测试,但我认为有些问题:虽然我的代码中的几乎所有代码都经过了 11 次测试,但所有导入和类定义行都被视为“缺失”,结果覆盖率报告仅为 49%。

我如何告诉coverage.py 计算这些行,因为它们 被执行了?

models.py

from werkzeug.security import generate_password_hash, check_password_hash
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
from itsdangerous import BadSignature, SignatureExpired
from flask import current_app
from flask_login import UserMixin

from app import db


class User(UserMixin, db.Model):
    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(64), unique=True, index=True)
    username = db.Column(db.String(64), unique=True)
    password_hash = db.Column(db.String(128))
    confirmed = db.Column(db.Boolean, default=False)

    @property
    def password(self):
        raise AttributeError('User.password is not readable.')

    @password.setter
    def password(self, value):
        self.password_hash = generate_password_hash(value)

    def check_password(self, password):
        return check_password_hash(self.password_hash, password)

    def generate_token(self, dict_, salt=None, expiration=3600):
        dict_.setdefault('user_id', self.id)
        s = Serializer(current_app.config['SECRET_KEY'], expiration, salt=salt)
        return s.dumps(dict_)

    def load_token(self, token, salt=None):
        s = Serializer(current_app.config['SECRET_KEY'], salt=salt)
        try:
            data = s.loads(token)
            if data.get('user_id') == self.id:
                return data
            else:
                return False
        except (BadSignature, SignatureExpired):
            return None

    def __repr__(self):
        return '<user %r>' % self.username

test_user_model.py

import unittest
from sqlalchemy.exc import IntegrityError

from app import create_app, db
from app.models import User


class UserModelTestCase(unittest.TestCase):
    def setUp(self):
        self.app = create_app('testing')
        self.app_context = self.app.app_context()
        self.app_context.push()
        db.create_all()

    def tearDown(self):
        db.session.remove()
        db.drop_all()
        self.app_context.pop()

    def test_email_unique(self):
        user = User(
            email = 'john@example.com',
            username = 'john',
            password = 'cat'
        )
        db.session.add(user)
        db.session.commit()
        user = User(
            email = 'john@example.com',
            username = 'alice',
            password = 'cat'
        )
        with self.assertRaises(IntegrityError):
            db.session.add(user)
            db.session.commit()

    def test_username_unique(self):
        user = User(
            email = 'john@example.com',
            username = 'john',
            password = 'cat'
        )
        db.session.add(user)
        db.session.commit()
        user = User(
            email = 'alice@example.com',
            username = 'john',
            password = 'cat'
        )
        with self.assertRaises(IntegrityError):
            db.session.add(user)
            db.session.commit()

    def test_user_not_confirmed(self):
        user = User(
            email = 'john@example.com',
            username = 'john',
            password = 'cat'
        )
        db.session.add(user)
        db.session.commit()
        user = User.query.get(1)
        self.assertFalse(user.confirmed)

    def test_password(self):
        user = User(
            email = 'john@example.com',
            username = 'john',
            password = 'cat'
        )
        self.assertTrue(user.check_password('cat'))
        self.assertFalse(user.check_password('Cat'))

    def test_password_unreadable(self):
        user = User(
            email = 'john@example.com',
            username = 'john',
            password = 'cat'
        )
        with self.assertRaises(AttributeError):
            user.password

    def test_password_hash(self):
        user1 = User(
            email='john@example.com',
            username='john',
            password='cat'
        )
        user2 = User(
            email='alice@example.com',
            username='alice',
            password='cat'
        )
        self.assertNotEqual(user1.password_hash, user2.password_hash)

    def test_repr(self):
        user = User(
            email = 'john@example.com',
            username = 'john',
            password = 'cat'
        )
        self.assertEqual(repr(user), "<user 'john'>")

    def test_generate_token(self):
        user1 = User(
            email = 'john@example.com',
            username = 'john',
            password = 'cat'
        )
        user2 = User(
            email = 'alice@example.com',
            username = 'alice',
            password = 'cat'
        )
        db.session.add_all([user1, user2])
        db.session.commit()

        token = user1.generate_token({'foo': 'bar'}, salt='test')
        self.assertIsNotNone(token)

        data = user1.load_token(token, salt='test')
        self.assertIsNotNone(data)
        self.assertEqual(data.get('foo'), 'bar')

        data = user1.load_token(token, salt='Test')
        self.assertIsNone(data)

        data = user2.load_token(token, salt='test')
        self.assertIsNotNone(data)
        self.assertFalse(data)

启动测试的函数:

def test():
    """Run unit tests"""
    cov = Coverage(branch=True, source=['app'])
    cov.start()
    try:
        tests = unittest.defaultTestLoader.discover('tests')
        unittest.TextTestRunner(verbosity=2).run(tests)
    except:
        pass
    cov.stop()
    cov.save()

    cov.report()
    basedir = os.path.realpath(os.path.dirname(__file__))
    covdir = os.path.join(basedir, 'cov_report')
    cov.html_report(directory=covdir)
    cov.erase()

这是覆盖率报告:

test_app_exist (test_basics.BasicsTestCase) ... ok
test_db_exist (test_basics.BasicsTestCase) ... ok
test_test (test_basics.BasicsTestCase) ... ok
test_email_unique (test_user_model.UserModelTestCase) ... ok
test_generate_token (test_user_model.UserModelTestCase) ... ok
test_password (test_user_model.UserModelTestCase) ... ok
test_password_hash (test_user_model.UserModelTestCase) ... ok
test_password_unreadable (test_user_model.UserModelTestCase) ... ok
test_repr (test_user_model.UserModelTestCase) ... ok
test_user_not_confirmed (test_user_model.UserModelTestCase) ... ok
test_username_unique (test_user_model.UserModelTestCase) ... ok

----------------------------------------------------------------------
Ran 11 tests in 1.227s

OK
Name                   Stmts   Miss Branch BrPart  Cover
--------------------------------------------------------
app/__init__.py           30     18      0      0    40%
app/auth/__init__.py       3      3      0      0     0%
app/auth/forms.py         22     22      4      0     0%
app/auth/views.py         54     54     16      0     0%
app/main/__init__.py       3      3      0      0     0%
app/main/views.py          4      4      0      0     0%
app/models.py             33     18      2      0    49%
app/send_mail.py          17     17      0      0     0%
--------------------------------------------------------
TOTAL                    166    139     22      0    15%

【问题讨论】:

    标签: python unit-testing flask sqlalchemy code-coverage


    【解决方案1】:

    这意味着您将在文件导入后开始覆盖。不要使用你自己的代码来启动覆盖,使用覆盖命令行工具来运行你的测试运行器。

    【讨论】:

    • 我该怎么做?
    猜你喜欢
    • 2015-07-10
    • 1970-01-01
    • 2016-10-31
    • 2013-01-28
    • 2020-09-27
    • 1970-01-01
    • 2019-10-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多