• 2 Selenium Python 框架基础


    1 单元测试

    1.1 什么是单元测试?

    单元测试(unit testing),是指对软件中的最小可测试单元进行检查和验证。

    对于单元测试中单元的含义,一般来说,要根据实际情况去判定其具体含义,如C语言中单元指一个函数,Java里单元指一个类。

    总的来说,单元就是人为规定的最小的被测功能模块。

    单元测试是在软件开发过程中要进行的最低级别的测试活动,软件的独立单元将在与程序的其他部分相隔离的情况下进行测试。

    1.2 名词解释

      单元测试主要包含概念如下:test case、test suite、test runner、test fixture

    • test case:

      一个TestCase的实例就是一个测试用例。

      什么是测试用例呢?就是一个完整的测试流程,包括测试前准备环境的搭建(setUp),执行测试代码(run),以及测试后环境的还原(tearDown)。

    • test suite:

      而多个测试用例集合在一起,就是TestSuite,而且TestSuite也可以嵌套TestSuite。

      TestLoader是用来加载TestCase到TestSuite中的,其中有几个loadTestsFrom__()方法,就是从各个地方寻找TestCase,创建它们的实例,

      然后add到TestSuite中,再返回一个TestSuite实例。

    • test runner:

      TextTestRunner是来执行测试用例的,其中的run(test)会执行TestSuite/TestCase中的run(result)方法。

      测试的结果会保存到TextTestResult实例中,包括运行了多少测试用例,成功了多少,失败了多少等信息。

    • test fixture:

      对一个测试用例环境的搭建和销毁,是一个fixture,通过覆盖TestCase的setUp()和tearDown()方法来实现。

      这个有什么用呢?比如说在这个测试用例中需要访问数据库,那么可以在setUp()中建立数据库连接以及进行一些初始化,在tearDown()中清除在数据库中产生的数据,

      然后关闭连接。注意tearDown的过程很重要,要为以后的TestCase留下一个干净的环境。

     1.3 如何单元测试

     1 #被测类
     2 class Index(object):
     3     
     4     def login(self , username , password):
     5         if username == 'root' and password == '123456':
     6             print '登录成功 !'
     7         else:
     8             print '用户名或密码错误 !'
     9         
    10 #单元测试
    11 import unittest2
    12 
    13 class TestLogin(unittest2.TestCase):
    14     index = Index()
    15     
    16     def testLoginSuccess(self):   
    17         self.index.login('root', '123456')
    18     
    19     def testLoginUsernameError(self):
    20         self.index.login('aaron', '123456')
    21         print '--用户名错误'
    22         
    23     def testLoginPasswordError(self):
    24         self.index.login('root', '654321')
    25         print '--密码错误'
    26         
    27 #执行测试
    28 if __name__ == '__main__':
    29     unittest2.main()
    30 
    31 #结果
    32 用户名或密码错误 !
    33 --密码错误
    34 登录成功 !
    35 用户名或密码错误 !
    36 --用户名错误
    View Code

     1.4 执行测试的不同方法

    • 使用unittest.main()执行测试用例
    • 使用testsuit来执行测试用例
    • 使用TestLoader构建suite来执行测试用例
     1 #被测类
     2 class Index(object):
     3     
     4     def login(self , username , password):
     5         if username == 'root' and password == '123456':
     6             print '登录成功 !'
     7         else:
     8             print '用户名或密码错误 !'
     9     def search(self , item):
    10         if item == 'Python':
    11             print '搜索成功 !'
    12         else:
    13             print '搜索失败 !'
    14         
    15 #单元测试
    16 import unittest2
    17 
    18 class TestLogin(unittest2.TestCase):
    19     index = Index()
    20     
    21     def testLoginSuccess(self):   
    22         self.index.login('root', '123456')
    23     
    24     def testLoginUsernameError(self):
    25         self.index.login('aaron', '123456')
    26         print '--用户名错误'
    27         
    28     def testLoginPasswordError(self):
    29         self.index.login('root', '654321')
    30         print '--密码错误'
    31         
    32 class TestSearch(unittest2.TestCase):  
    33     index = Index()
    34     
    35     def testSearchSuccess(self):   
    36         self.index.search('Python')
    37     
    38     def testSearchFail(self):
    39         self.index.search('Java')
    40 
    41 #使用unittest.main()执行测试用例------
    42 if __name__ == '__main__':
    43     unittest2.main()
    44 
    45 #使用addTest构建suite来执行测试用例------
    46 if __name__ == '__main__':
    47     #以测试用例为单位构造测试集
    48     #TestSuit:组织测试用例的实例,支持测试用例的添加和删除,最终将传递给  testRunner进行测试执行
    49     suite = unittest2.TestSuite()
    50     suite.addTest(TestLogin.testLoginSuccess())
    51     suite.addTest(TestLogin.testLoginUsernameError())
    52     suite.addTest(TestLogin.testLoginPasswordError())
    53     #执行测试
    54     #TextTestRunner:进行测试用例执行的实例,其中Text的意思是以文本形式显示测试结果。
    55     #测试的结果会保存到TextTestResult实例中,包括运行了多少测试用例,成功了多少,失败了多少等信息
    56     runner = unittest2.TextTestRunner()
    57     runner.run(suite)
    58     
    59 #使用TestLoader构建suite来执行测试用例------
    60 if __name__ == '__main__':
    61     #以测试类为单位构造测试集
    62     #TestLoader:用来加载TestCase到TestSuite中
    63     #其中有几个  loadTestsFromXX()方法,就是从各个地方寻找TestCase,创建它们的实例
    64     #然后add到TestSuite中,再返回一个TestSuite实例;
    65     suite1 = unittest2.TestLoader().loadTestsFromTestCase(TestLogin)
    66     suite2 = unittest2.TestLoader().loadTestsFromTestCase(TestSearch)
    67     suite = unittest2.TestSuite([suite1 , suite2])  
    68     unittest2.TextTestRunner(verbosity=2).run(suite)
    View Code

     1.5 测试执行顺序

    • setUpClass:类中所有用例执行前执行一次
    • tearDownClass:类中所有用例执行后执行一次
    • setUp:每个用例执行前执行一次
    • tearDown:每个用例执行后执行一次
    • 测试用例执行顺序:用例名称test后面按字母顺序执行
     1 import unittest2
     2 
     3 class TestDemo(unittest2.TestCase):
     4     @classmethod
     5     def setUpClass(self):
     6         print 'setUpClass'
     7     @classmethod
     8     def tearDownClass(self):
     9         print 'tearDownClass'
    10     def setUp(self):
    11         print 'setUp'
    12     def tearDown(self):
    13         print 'tearDown'
    14     def testLogin(self):
    15         print 'login'
    16     def testAdd(self):
    17         print 'add'
    18     def testUpdate(self):
    19         print 'update'
    20     def testLogout(self):
    21         print 'logout'
    22 
    23 #使用unittest.main()执行测试用例------
    24 if __name__ == '__main__':
    25     unittest2.main()
    26 
    27 #结果
    28 setUpClass
    29 setUp
    30 add
    31 tearDown
    32 setUp
    33 login
    34 tearDown
    35 setUp
    36 logout
    37 tearDown
    38 setUp
    39 update
    40 tearDown
    41 tearDownClass
    View Code

    2 测试报告

    2.1 测试报告

    报告名称:HTMLTestRunner为单元测试报告

    下载地址:http://tungwaiyip.info/software/HTMLTestRunner.html

    使用方法:HTMLTestRunner.py文件放在C:Python27Lib下

     1 #被测类
     2 import unittest2
     3 import time
     4 import HTMLTestRunner
     5 
     6 class TestDemo(unittest2.TestCase):
     7     @classmethod
     8     def setUpClass(self):
     9         print 'setUpClass'
    10     @classmethod
    11     def tearDownClass(self):
    12         print 'tearDownClass'
    13     def testLogin(self):
    14         print 'login'
    15     def testAdd(self):
    16         print 'add'
    17     def testUpdate(self):
    18         print 'update'
    19     def testLogout(self):
    20         print 'logout'
    21 
    22 #测试类
    23 import time
    24 import HTMLTestRunner
    25 from testcase.demo5 import *
    26 
    27 #使用addTest构建suite来执行测试用例------
    28 suite = unittest2.TestSuite()
    29 suite.addTest(TestDemo('testAdd'))
    30 #报告准备
    31 reportName = time.strftime('%Y%m%d%H%M%S')             #文件名
    32 fp = open('../' + reportName + '.html' , 'wb')         #文件路径
    33 runner = HTMLTestRunner.HTMLTestRunner(stream = fp ,   #定义报告
    34                                        title = '测试报告' ,
    35                                        description = '自动化测试报告Demo')
    36 #执行测试
    37 result = runner.run(suite)
    38 #关闭文件
    39 fp.close()
    40 print result
    41 
    42 #测试结果
    43 Finding files... done.
    44 Importing test modules ... setUpClass
    45 tearDownClass
    46 .
    47 Time Elapsed: 0:00:00
    48 <HTMLTestRunner._TestResult run=1 errors=0 failures=0>
    View Code

    2.2 文档注释

    python在注释中有一个非常有用的东西是 doc String ,它可以用于模块、函数和类的描述。

    使用三个双引号或三个单引号进行注释。

    文档字符串的惯例是一个多行字符串,它的首行以大写字母开始,句号结尾。第二行是空行,从第三行开始是详细的描述。

     1 #被测类
     2 #!/usr/bin/env python
     3 # coding=utf-8
     4 
     5 import unittest2
     6 import time
     7 import HTMLTestRunner
     8 
     9 class TestDemo(unittest2.TestCase):
    10     '''(测试Demo类)'''
    11     @classmethod
    12     def setUpClass(self):
    13         print 'setUpClass'
    14     @classmethod
    15     def tearDownClass(self):
    16         print 'tearDownClass'
    17         
    18     def testLogin(self):
    19         """(登录)"""
    20         print 'login'
    21 
    22     def testAdd(self):
    23         '''(新增)'''
    24         print 'add'
    25     
    26     def testUpdate(self):
    27         '''(修改)'''
    28         print 'update'
    29 
    30     def testLogout(self):
    31         '''(退出)'''
    32         print 'logout'
    33 
    34 #测试类
    35 #!/usr/bin/env python
    36 # coding=utf-8
    37 
    38 import time
    39 import HTMLTestRunner
    40 from testcase.demo5 import *
    41 
    42 #使用addTest构建suite来执行测试用例------
    43 suite = unittest2.TestSuite()
    44 suite.addTest(TestDemo('testLogin'))
    45 suite.addTest(TestDemo('testAdd'))
    46 suite.addTest(TestDemo('testUpdate'))
    47 suite.addTest(TestDemo('testLogout'))
    48 #报告准备
    49 reportName = time.strftime('%Y%m%d%H%M%S')             #文件名
    50 fp = open('../' + reportName + '.html' , 'wb')         #文件路径
    51 runner = HTMLTestRunner.HTMLTestRunner(stream = fp ,   #定义报告
    52                                        title = '测试报告' ,
    53                                        description = '自动化测试报告Demo')
    54 #执行测试
    55 result = runner.run(suite)
    56 #关闭文件
    57 fp.close()
    58 print result
    View Code

     3 配置文件

    3.1 配置文件

    1 #配置selenium
    2 [selenium]
    3 browser = firefox
    4 timeout = 10
    View Code

    3.2 操作配置文件

    Python标准库的ConfigParser模块提供一套API操作配置文件。

     1 #!/usr/bin/env python
     2 # coding=utf-8
     3 
     4 import ConfigParser
     5 
     6 class Configer(object):
     7     
     8     #构造函数,初始化ConfigParser类,并读取config文件
     9     def __init__(self , filePath):
    10         self.conf = ConfigParser.ConfigParser()
    11         self.conf.read(filePath)
    12     
    13     #获取key的value 
    14     def getConf(self , section , key):
    15         result = self.conf.get(section, key)
    16         return result
    View Code

    3.3 配置文件解析

    将配置文件中内容解析出来方便使用

    1 #!/usr/bin/env python
    2 # coding=utf-8
    3 
    4 from libs.Configer import *
    5 
    6 class SelConf(object):
    7     conf = Configer("../config/selenium.conf")
    8     browser = conf.getConf('selenium', 'browser')
    9     timeout = conf.getConf('selenium', 'timeout')
    View Code

    3.4 配置文件使用

     1 #!/usr/bin/env python
     2 # coding=utf-8
     3 
     4 from config.SeleniumConf import *
     5 
     6 if __name__ == '__main__':
     7     print SelConf.browser
     8 
     9 #结果
    10 firefox
    View Code

     4 日志

    4.1 logging模块四大类

    python通过logging模块提供简单易用、且功能强大的日志功能。logging模块四大类如下:

    • logger:提供了应用程序可以直接使用的接口
    • handler将(logger创建的)日志发送到指定的输出路径
    • filter决定输出哪条日志
    • formatter决定日志的最终输出格式

    4.1.1 logger类

    每个程序在输出信息之前都要通过 logging.getlogger() 来获得一个log实例

    源码如下:

    def getLogger(name=None):

    """
    Return a logger with the specified name, creating it if necessary.

    If no name is specified, return the root logger.
    """
    if name:
    return Logger.manager.getLogger(name)
    else:
    return root

    logger的level有以下几个级别:NOTSET < DEBUG < INFO < WARNING < ERROR < CRITICAL

    如果把looger的级别设置为INFO, 那么小于INFO级别的日志都不输出, 大于等于INFO级别的日志都输出

    4.1.2 handlers

    handler对象负责发送相关的信息到指定目的地。如:控制台、文件、网络等

    4.1.3 Formatters

    Formatter对象设置日志信息格式,默认的时间格式为%Y-%m-%d %H:%M:%S

    关于formatter的配置,采用的是%(<dict key>)s的形式,就是字典的关键字替换。提供的关键字包括:

    • %(name)s             Name of the logger (logging channel).
    • %(levelno)s           Numeric logging level for the message (DEBUG, INFO, WARNING, ERROR, CRITICAL).
    • %(levelname)s       Text logging level for the message ('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL').
    • %(pathname)s       Full pathname of the source file where the logging call was issued (if available).
    • %(filename)s         Filename portion of pathname.
    • %(module)s           Module (name portion of filename).
    • %(funcName)s       Name of function containing the logging call.
    • %(lineno)d            Source line number where the logging call was issued (if available).
    • %(created)f           Time when the LogRecord was created (as returned by time.time()).
    • %(relativeCreated)d     Time in milliseconds when the LogRecord was created, relative to the time the logging module was loaded.
    • %(asctime)s          Human-readable time when the LogRecord was created. By default this is of the form “2003-07-08 16:49:45,896” (the numbers after the comma are millisecond portion of the time).
    • %(msecs)d            Millisecond portion of the time when the LogRecord was created.
    • %(thread)d           Thread ID (if available).
    • %(threadName)s   Thread name (if available).
    • %(process)d          Process ID (if available).
    • %(message)s        The logged message, computed as msg % args.

     4.1.4 TimeRotatingFileHandler

    TimeRotatingFileHandler根据时间日志文件的记录。

    格式:TimedRotatingFileHandler(filename [,when [,interval [,backupCount]]])

    • filename 是输出日志文件名的前缀
    • when 是一个字符串的定义如下:

    “S”: Seconds
    “M”: Minutes
    “H”: Hours
    “D”: Days
    “W”: Week day (0=Monday)
    “midnight”: Roll over at midnight

    • interval 是指等待多少个单位when的时间后,Logger会自动重建文件
    • backupCount 是保留日志个数。默认的0是不会自动删除掉日志。若设10,则在文件的创建过程中库会判断是否有超过这个10,若超过,则会从最先创建的开始删除。

     4.2 实战

    4.2.1 log配置文件

     1 ###############################################
     2 #root 必须有
     3 #propagate 是否继承父类的log信息,0:否 1:是
     4 #propagate 默认1,如果设置为1会打印两次
     5 #handlers  对应下面handler
     6 #qualname  getLogger时输入的名字
     7 ###############################################
     8 
     9 [loggers]
    10 keys = root,errorLogger
    11 
    12 [logger_root]
    13 level = ERROR
    14 handlers = errorHandler
    15 
    16 [logger_errorLogger]
    17 level = ERROR
    18 propagate = 0
    19 handlers = errorHandler
    20 qualname = errorLogger
    21 
    22 ###############################################
    23 #按照时间的滚动方式记录日志
    24 #formatter 对应下面日志格式
    25 ###############################################
    26 
    27 [handlers]
    28 keys = errorHandler
    29 
    30 [handler_errorHandler]
    31 class=logging.handlers.TimedRotatingFileHandler
    32 level=ERROR
    33 args = ('../logs/selenium.log','D',1,5,) 
    34 formatter = errorFmt
    35 
    36 ###############################################
    37 #日志格式
    38 ###############################################
    39 
    40 [formatters]
    41 keys = errorFmt
    42 
    43 [formatter_errorFmt]
    44 class = logging.Formatter
    45 format = %(asctime)s - %(levelname)s - %(filename)s - %(funcName)s - [line:%(lineno)d] - %(message)s
    46 datefmt = %Y-%m-%d %H:%M:%S
    View Code

    4.2.2 初始化文件

     1 #!/usr/bin/python
     2 # coding=utf8
     3 
     4 import ConfigParser
     5 import logging
     6 import logging.config
     7 
     8 class Logger(object):
     9     
    10     @staticmethod
    11     def append():
    12         logging.config.fileConfig('../config/logger.conf')
    13         append = logging.getLogger("errorLogger")
    14         return append
    View Code

    4.2.3 测试

     1 #!/usr/bin/python
     2 # coding=utf8
     3 
     4 from libs.Logger import *
     5 
     6 def testLog():
     7     Logger.append().error('error11111')
     8 
     9 def testLog2():
    10     Logger.append().error('error22222')
    11 
    12 if __name__ == '__main__':
    13     testLog()
    14     testLog2()
    15 
    16 #结果 - 文件
    17 selenium.log
    18 selenium.log.2017-03-14
    19 
    20 #结果 - 内容
    21 2017-04-02 23:32:33 - ERROR - testConfig.py - testLog - [line:7] - error11111
    22 2017-04-02 23:32:33 - ERROR - testConfig.py - testLog2 - [line:11] - error22222
    View Code

     5 邮件

    5.1 简介

    SMTP(Simple Mail Transfer Protocol)即简单邮件传输协议

    Python对SMTP支持有smtplib和email两个模块,email负责构造邮件,smtplib负责发送邮件

    可以发送纯文本邮件、HTML邮件、带附件的邮件等

    发送邮件时,我们一般使用第三方SMTP服务,163邮箱的SMTP服务开启步骤:进入163邮箱 - 设置 - POP3/SMTP/IMAP

    POP3与SMTP区别:POP3用于接收邮件;SMTP用于发送邮件

    5.1 构造邮件

    email.mime:creating email and MIME objects from scratch,也就是一点点地构造一封邮件

    • MIMEText对象,表示一个文本邮件
    • MIMEImage对象,表示一个作为附件的图片
    • MIMEMultipart对象,表示把多个对象组合起来
    • MIMEBase对象,可以表示任何对象

     5.2 发送文本邮件

     1 #配置文件================
     2 [email]
     3 #构造邮件
     4 from_addr=XXX@163.com
     5 to_addr=XXX@qq.com
     6 #发送邮件
     7 host=smtp.163.com
     8 port=25
     9 user=XXX@163.com
    10 password=XXX
    11 
    12 #解析文件================
    13 #!/usr/bin/env python
    14 # coding=utf-8
    15 
    16 from libs.Configer import *
    17 
    18 class email(object):
    19     conf = Configer("../config/email.conf")
    20     #构造邮件
    21     from_addr = conf.getConf('email', 'from_addr')
    22     to_addr = conf.getConf('email', 'to_addr') 
    23     #发送邮件
    24     host = conf.getConf('email', 'host')
    25     port = conf.getConf('email', 'port')
    26     user = conf.getConf('email', 'user')
    27     password = conf.getConf('email', 'password')
    28 
    29 #测试文件================
    30 #!/usr/bin/python
    31 # coding=utf8
    32 
    33 from libs.email import *
    34 from email.mime.text import MIMEText
    35 from email.header import Header
    36 #构造邮件
    37 msg = MIMEText('请大家自学Python...', 'plain', 'utf-8')  #邮件主体
    38 #不赋值msg['Subject']、msg['From']、msg['To'],会导致出现554情况
    39 msg['Subject'] = Header('请大家自学Python', 'utf-8')    #邮件标题
    40 msg['From'] = email.from_addr  #发件人   
    41 msg['To'] = email.to_addr #收件人
    42  
    43 import smtplib
    44 #发送邮件
    45 server = smtplib.SMTP() 
    46 server.connect(email.host, int(email.port))  # 连接网易SMTP服务,默认端口号25
    47 # server.set_debuglevel(1)    #打印与SMTP服务器交互的所有信息
    48 server.login(email.from_addr, email.password)   #登录
    49 server.sendmail(email.from_addr, email.to_addr, msg.as_string()) #发送邮件,传入msg
    50 server.quit()
    View Code

     163退信的常见问题连接:http://help.163.com/09/1224/17/5RAJ4LMH00753VB8.html

    5.3 给多人发送邮件

    • 配置文件修改:to_addr=XXX@qq.com;XXX@163.com
    • email解析文件修改:to_addr = conf.getConf('email', 'to_addr').split(';')
    • 测试文件修改:msg['To'] = ";".join(email.to_addr) #收件人
     1 #配置文件=============================
     2 [email]
     3 #构造邮件
     4 from_addr=XXX@163.com
     5 to_addr=XXX@qq.com;XXX@163.com
     6 #发送邮件
     7 host=smtp.163.com
     8 port=25
     9 user=XXX@163.com
    10 password=XXX
    11 
    12 #解析文件=============================
    13 #!/usr/bin/env python
    14 # coding=utf-8
    15 
    16 from libs.Configer import *
    17 
    18 class email(object):
    19     conf = Configer("../config/email.conf")
    20     #构造邮件
    21     from_addr = conf.getConf('email', 'from_addr')
    22     to_addr = conf.getConf('email', 'to_addr').split(';') 
    23     #发送邮件
    24     host = conf.getConf('email', 'host')
    25     port = conf.getConf('email', 'port')
    26     user = conf.getConf('email', 'user')
    27     password = conf.getConf('email', 'password')
    28 
    29 #测试文件=============================
    30 #!/usr/bin/python
    31 # coding=utf8
    32 
    33 from libs.email import *
    34 from email.mime.text import MIMEText
    35 from email.header import Header
    36 
    37 #构造邮件
    38 msg = MIMEText('请大家自学Python...', 'plain', 'utf-8')  #邮件主体
    39 #不赋值msg['Subject']、msg['From']、msg['To'],会导致出现554情况
    40 msg['Subject'] = Header('请大家自学Python', 'utf-8')    #邮件标题
    41 msg['From'] = email.from_addr  #发件人   
    42 msg['To'] = ";".join(email.to_addr) #收件人
    43   
    44 import smtplib
    45 #发送邮件
    46 server = smtplib.SMTP() 
    47 server.connect(email.host, int(email.port))  # 连接网易SMTP服务,默认端口号25
    48 # server.set_debuglevel(1)    #打印与SMTP服务器交互的所有信息
    49 server.login(email.from_addr, email.password)   #登录
    50 server.sendmail(email.from_addr, email.to_addr, msg.as_string()) #发送邮件,传入msg
    51 server.quit()
    View Code

    5.4 发送html邮件

    msg = MIMEText('<html><a href="http://www.cnblogs.com/lizitest/">栗子自学Python</a></html>', 'html', 'utf-8')

    注意:

    • 163不支持群发html邮件
    • 163邮箱需要<html>标签,其他邮箱没试过
     1 #配置文件================
     2 [email]
     3 #构造邮件
     4 from_addr=XXX@163.com
     5 to_addr=XXX@qq.com
     6 #发送邮件
     7 host=smtp.163.com
     8 port=25
     9 user=XXX@163.com
    10 password=XXX
    11 
    12 #解析文件================
    13 #!/usr/bin/env python
    14 # coding=utf-8
    15 
    16 from libs.Configer import *
    17 
    18 class email(object):
    19     conf = Configer("../config/email.conf")
    20     #构造邮件
    21     from_addr = conf.getConf('email', 'from_addr')
    22     to_addr = conf.getConf('email', 'to_addr').split(';') 
    23     #发送邮件
    24     host = conf.getConf('email', 'host')
    25     port = conf.getConf('email', 'port')
    26     user = conf.getConf('email', 'user')
    27     password = conf.getConf('email', 'password')
    28 
    29 #测试文件================
    30 #!/usr/bin/python
    31 # coding=utf8
    32 
    33 from libs.email import *
    34 from email.mime.text import MIMEText
    35 from email.header import Header
    36 
    37 #构造邮件
    38 msg = MIMEText('<html><a href="http://www.cnblogs.com/lizitest/">栗子自学Python</a></html>', 'html', 'utf-8')
    39 msg['Subject'] = Header('请大家自学Python', 'utf-8')    #邮件标题
    40 msg['From'] = email.from_addr  #发件人   
    41 msg['To'] = ";".join(email.to_addr) #收件人
    42   
    43 import smtplib
    44 #发送邮件
    45 server = smtplib.SMTP() 
    46 server.connect(email.host, int(email.port))  # 连接网易SMTP服务,默认端口号25
    47 server.set_debuglevel(1)    #打印与SMTP服务器交互的所有信息
    48 server.login(email.from_addr, email.password)   #登录
    49 server.sendmail(msg['From'], msg['To'], msg.as_string()) #发送邮件,传入msg
    50 server.quit()
    View Code

     5.5发送带附件的邮件

    附件和文本均可以看作是邮件的一部分,先使用 MIMEMultipart 对象来表示邮件,再往邮件中添加正文和附件(MIMEText)

     1 #配置文件================
     2 [email]
     3 #构造邮件
     4 from_addr=XXX@163.com
     5 to_addr=XXX@qq.com
     6 #发送邮件
     7 host=smtp.163.com
     8 port=25
     9 user=XXX@163.com
    10 password=XXX
    11 
    12 #解析文件================
    13 #!/usr/bin/env python
    14 # coding=utf-8
    15 
    16 from libs.Configer import *
    17 
    18 class email(object):
    19     conf = Configer("../config/email.conf")
    20     #构造邮件
    21     from_addr = conf.getConf('email', 'from_addr')
    22     to_addr = conf.getConf('email', 'to_addr').split(';') 
    23     #发送邮件
    24     host = conf.getConf('email', 'host')
    25     port = conf.getConf('email', 'port')
    26     user = conf.getConf('email', 'user')
    27     password = conf.getConf('email', 'password')
    28 
    29 #测试文件================
    30 #!/usr/bin/python
    31 # coding=utf8
    32 
    33 from libs.email import *
    34 from email.mime.multipart import MIMEMultipart
    35 from email.mime.text import MIMEText
    36 from email.header import Header
    37 
    38 #构造邮件
    39 msg = MIMEMultipart()
    40 msg['Subject'] = Header('请大家自学Python', 'utf-8')    #邮件标题
    41 msg['From'] = email.from_addr  #发件人   
    42 msg['To'] = ";".join(email.to_addr) #收件人
    43 #添加正文
    44 body = MIMEText('<html><a href="http://www.cnblogs.com/lizitest/">栗子自学Python</a></html>', 'html', 'utf-8')
    45 msg.attach(body)
    46 #添加附件1
    47 att = MIMEText(open('../logs/selenium.log', 'rb').read(), 'base64', 'utf-8')  
    48 att["Content-Type"] = 'application/octet-stream'  
    49 att["Content-Disposition"] = 'attachment; filename="selenium.log"'  
    50 msg.attach(att)  
    51 #添加附件2
    52 att = MIMEText(open('../logs/selenium.log.2017-03-30', 'rb').read(), 'base64', 'utf-8')  
    53 att["Content-Type"] = 'application/octet-stream'  
    54 att["Content-Disposition"] = 'attachment; filename="selenium.log.2017-03-30"'  
    55 msg.attach(att) 
    56   
    57 import smtplib
    58 #发送邮件
    59 server = smtplib.SMTP() 
    60 server.connect(email.host, int(email.port))  # 连接网易SMTP服务,默认端口号25
    61 server.set_debuglevel(1)    #打印与SMTP服务器交互的所有信息
    62 server.login(email.from_addr, email.password)   #登录
    63 server.sendmail(msg['From'], msg['To'], msg.as_string()) #发送邮件,传入msg
    64 server.quit()
    View Code

     5.6 发送带图片附件的邮件

    可以使用MIMEText进行发送,可以使用MIMEImage进行发送

     1 #配置文件================
     2 [email]
     3 #构造邮件
     4 from_addr=XXX@163.com
     5 to_addr=XXX@qq.com
     6 #发送邮件
     7 host=smtp.163.com
     8 port=25
     9 user=XXX@163.com
    10 password=XXX
    11 
    12 #解析文件================
    13 #!/usr/bin/env python
    14 # coding=utf-8
    15 
    16 from libs.Configer import *
    17 
    18 class email(object):
    19     conf = Configer("../config/email.conf")
    20     #构造邮件
    21     from_addr = conf.getConf('email', 'from_addr')
    22     to_addr = conf.getConf('email', 'to_addr').split(';') 
    23     #发送邮件
    24     host = conf.getConf('email', 'host')
    25     port = conf.getConf('email', 'port')
    26     user = conf.getConf('email', 'user')
    27     password = conf.getConf('email', 'password')
    28 
    29 #测试文件================
    30 #!/usr/bin/python
    31 # coding=utf8
    32 
    33 from libs.email import *
    34 from email.mime.multipart import MIMEMultipart
    35 from email.mime.text import MIMEText
    36 from email.mime.image import MIMEImage
    37 from email.header import Header
    38 
    39 #构造邮件
    40 msg = MIMEMultipart()
    41 msg['Subject'] = Header('请大家自学Python', 'utf-8')    #邮件标题
    42 msg['From'] = email.from_addr  #发件人   
    43 msg['To'] = ";".join(email.to_addr) #收件人
    44 #添加正文
    45 body = MIMEText('<html>' + 
    46         '<a href="http://www.cnblogs.com/lizitest/">栗子自学Python</a>' +
    47 #         '<p><img src="cid:report"></p>' +
    48         '</html>', 'html', 'utf-8')
    49 msg.attach(body)
    50 #添加附件1
    51 file1 = open('../logs/selenium.log', 'rb') 
    52 att = MIMEText(file1.read(), 'base64', 'utf-8')
    53 file1.close()  
    54 att["Content-Type"] = 'application/octet-stream'  
    55 att["Content-Disposition"] = 'attachment; filename="selenium.log"'  
    56 msg.attach(att)  
    57 #添加附件2
    58 file2 = open('../logs/selenium.log.2017-03-30', 'rb') 
    59 att = MIMEText(file2.read(), 'base64', 'utf-8')  
    60 file2.close()  
    61 att["Content-Type"] = 'application/octet-stream'  
    62 att["Content-Disposition"] = 'attachment; filename="selenium.log.2017-03-30"'  
    63 msg.attach(att) 
    64 #添加图片附件1
    65 file3 = open('../logs/report.jpg', 'rb')
    66 msgImage = MIMEImage(file3.read()) 
    67 file3.close()
    68 msgImage.add_header('Content-ID', 'report') 
    69 msg.attach(msgImage)
    70 #添加图片附件2
    71 #file3 = open('../logs/report.jpg', 'rb') 
    72 #att = MIMEText(file3.read(), 'base64', 'utf-8')  
    73 #file3.close()
    74 # att["Content-Type"] = 'application/octet-stream'  
    75 # att["Content-Disposition"] = 'attachment; filename="report"'  
    76 # msg.attach(att) 
    77   
    78 import smtplib
    79 #发送邮件
    80 server = smtplib.SMTP() 
    81 server.connect(email.host, int(email.port))  # 连接网易SMTP服务,默认端口号25
    82 server.set_debuglevel(1)    #打印与SMTP服务器交互的所有信息
    83 server.login(email.from_addr, email.password)   #登录
    84 server.sendmail(msg['From'], msg['To'], msg.as_string()) #发送邮件,传入msg
    85 server.quit()
    View Code
  • 相关阅读:
    git的突出解决--git rebase之abort、continue、skip
    servlet中service() 和doGet() 、doPost() 学习笔记
    Spring IoC容器初始化过程学习
    浅探SpringMVC中HandlerExecutionChain之handler、interceptor
    常用路由命令
    路由配置命令
    cout 计算顺序问题
    第一次作业
    记录一个微信网页授权中不小心踩到的坑(Curl请求返回false)
    善用mysql中的FROM_UNIXTIME()函数和UNIX_TIMESTAMP()函数
  • 原文地址:https://www.cnblogs.com/lizitest/p/6622274.html
Copyright © 2020-2023  润新知