我已成功通过robotemail.py 脚本发送带有测试结果的邮件,但我想将附件(log.html)添加到邮件中,但我未能做到这一点。有人可以帮助我吗?
这是脚本:
#!/usr/bin/python
import smtplib
import email.message
import mimetypes
import sys
import os
import math
from datetime import datetime
from datetime import timedelta
from robot.api import ExecutionResult, ResultVisitor
from email.message import EmailMessage
# ======= START OF EMAIL SETUP CONTENT ====== #
# email set-up
server = smtplib.SMTP('XXXXXX')
msg = email.message.Message()
msg['Subject'] = 'smoke test'
sender = '[email protected]'
recipients = ['[email protected]']
msg['From'] = sender
msg['To'] = ", ".join(recipients)
password = "XXXXXX"
msg.add_header('Content-Type', 'text/html')
我想这里是添加附件代码的空间
# ======= END OF EMAIL SETUP CONTENT ====== #
**I have excluded big chunk of code**
# ====== EMAIL CONTENT ========== #
email_content = """
XXXXXXXXXXXXXXX
""" % (total_suite, passed_suite, failed_suite, suitepp, total, passed, failed, testpp, total_keywords, passed_keywords,
failed_keywords, kwpp, elapsedtime, generator)
msg.set_payload(email_content)
# Start server
server.starttls()
# Login Credentials for sending the mail
server.login(msg['From'], password)
server.sendmail(sender, recipients, msg.as_string())
# ==== END OF EMAIL CONTENT ====== #
有人可以帮助我吗?
我自己已经成功做到了。这是代码:
import smtplib, ssl, email
import email.message
import mimetypes
import sys
import os
import math
from datetime import datetime
from datetime import timedelta
from robot.api import ExecutionResult, ResultVisitor
from email import encoders
from email.mime.base import MIMEBase
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.message import EmailMessage
sender_email = "XXXXXX"
receiver_email = "XXXXXX"
password = "XXXXXX"
# Create MIMEMultipart object
msg = MIMEMultipart("alternative")
msg["Subject"] = "smoke test"
msg["From"] = sender_email
msg["To"] = receiver_email
filename = "C:/robot/robot_scripts/Results/log.html"
# ======================== START OF CUSTOMIZE EMAIL CONTENT ================================== #
# Ignores following library keywords count in email report
ignore_library = [
'BuiltIn',
'SeleniumLibrary',
'String',
'Collections',
'DateTime',
]
# Ignores following type keywords count in email report
ignore_type = [
'foritem',
'for',
]
# ======================== END OF CUSTOMIZE EMAIL CONTENT ================================== #
# ====== START OF PATH SELECTION ======= #
# Report to support file location as arguments
# Source Code Contributed By : Ruud Prijs
def getopts(argv):
opts = {}
while argv:
if argv[0][0] == '-':
if argv[0] in opts:
opts[argv[0]].append(argv[1])
else:
opts[argv[0]] = [argv[1]]
argv = argv[1:]
return opts
myargs = getopts(sys.argv)
# input directory
if '-inputpath' in myargs:
path = os.path.abspath(os.path.expanduser(myargs['-inputpath'][0]))
else:
path = os.path.curdir
# output.xml file
if '-output' in myargs:
output_name = os.path.join(path, myargs['-output'][0])
else:
output_name = os.path.join(path, 'output.xml')
# ====== END OF PATH SELECTION ======= #
# ====== GET ROBOT METRICS ======= #
# Read output.xml file
result = ExecutionResult(output_name)
result.configure(stat_config={'suite_stat_level': 2,
'tag_stat_combine': 'tagANDanother'})
total_suite = 0
passed_suite = 0
failed_suite = 0
class SuiteResults(ResultVisitor):
def start_suite(self, suite):
suite_test_list = suite.tests
if not suite_test_list:
pass
else:
global total_suite
total_suite += 1
if suite.status == "PASS":
global passed_suite
passed_suite += 1
else:
global failed_suite
failed_suite += 1
result.visit(SuiteResults())
suitepp = math.ceil(passed_suite * 100.0 / total_suite)
elapsedtime = datetime(1970, 1, 1) + timedelta(milliseconds=result.suite.elapsedtime)
elapsedtime = elapsedtime.strftime("%X")
myResult = result.generated_by_robot
if myResult:
generator = "Robot"
else:
generator = "Rebot"
stats = result.statistics
total = stats.total.total
passed = stats.total.passed
failed = stats.total.failed
testpp = round(passed * 100.0 / total, 2)
total_keywords = 0
passed_keywords = 0
failed_keywords = 0
class KeywordResults(ResultVisitor):
def start_keyword(self, kw):
# Ignore library keywords
keyword_library = kw.libname
if any(library in keyword_library for library in ignore_library):
pass
else:
keyword_type = kw.type
if any(library in keyword_type for library in ignore_type):
pass
else:
global total_keywords
total_keywords += 1
if kw.status == "PASS":
global passed_keywords
passed_keywords += 1
else:
global failed_keywords
failed_keywords += 1
result.visit(KeywordResults())
kwpp = round(passed_keywords * 100.0 / total_keywords, 2)
# HTML Message Part
html = """
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Robotframework Metrics</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0 " />
<style>
body {
background-color:#white;
}
body, html, table,span,b {
font-family: Calibri, Arial, sans-serif;
font-size: 1em;
}
.pastdue { color: crimson; }
table {
border: 1px solid silver;
padding: 6px;
margin-left: 30px;
width: 600px;
}
thead {
text-align: center;
font-size: 1.1em;
background-color: #B0C4DE;
font-weight: bold;
color: #2D2C2C;
}
tbody {
text-align: center;
}
th {
word-wrap:break-word;
}
td {
height: 25px;
}
</style>
</head>
<body>
<span>Hi Team,<br>Following are the last ARC_UI smoke execution status.<br><br><b>Metrics:<b><br><br></span>
<table>
<thead>
<th style="width: 25vh;"> Stats </th>
<th style="width: 20vh;"> Total </th>
<th style="width: 20vh;"> Pass </th>
<th style="width: 20vh;"> Fail </th>
<th style="width: 15vh;"> Perc (%%)</th>
</thead>
<tbody>
<tr>
<td style="text-align: left;font-weight: bold;"> SUITE </td>
<td style="text-align: center;">%s</td>
<td style="text-align: center;">%s</td>
<td style="text-align: center;">%s</td>
<td style="text-align: center;">%s</td>
</tr>
<tr>
<td style="text-align: left;font-weight: bold;"> TESTS </td>
<td style="text-align: center;">%s</td>
<td style="text-align: center;">%s</td>
<td style="text-align: center;">%s</td>
<td style="text-align: center;">%s</td>
</tr>
<tr>
<td style="text-align: left;font-weight: bold;"> KEYWORDS </td>
<td style="text-align: center;">%s</td>
<td style="text-align: center;">%s</td>
<td style="text-align: center;">%s</td>
<td style="text-align: center;">%s</td>
</tr>
</tbody>
</table>
<span><br><b>Info:<b><br><br></span>
<table>
<tbody>
<tr>
<td style="text-align: left;font-weight: normal;width: 30vh;"> Execution Time </td>
<td style="text-align: center;font-weight: normal;">%s h</td>
</tr>
<tr>
<td style="text-align: left;font-weight: normal;width: 50vh;"> Generated By </td>
<td style="text-align: center;font-weight: normal;">%s</td>
</tr>
</tbody>
</table>
<span style="text-align: left;font-weight: normal;"><br>Please refer reports for detailed info.<br><br>Regards,<br>QA Team</span>
</body></html>
""" % (total_suite, passed_suite, failed_suite, suitepp, total, passed, failed, testpp, total_keywords, passed_keywords,
failed_keywords, kwpp, elapsedtime, generator)
part = MIMEText(html, "html")
msg.attach(part)
# Add Attachment
with open(filename, "rb") as attachment:
part = MIMEBase("application", "octet-stream")
part.set_payload(attachment.read())
encoders.encode_base64(part)
# Set mail headers
part.add_header(
"Content-Disposition",
"attachment", filename='log.html'
)
msg.attach(part)
# Create secure SMTP connection and send email
with smtplib.SMTP("smtp.XXXXXXX.com:587") as server:
server.starttls()
server.login(sender_email, password)
server.sendmail(
sender_email, receiver_email, msg.as_string()
)
嗨,你能帮我吗?我使用你的代码,但出现错误
File "C:\pythonProject5\robotemail.py", line 274, in <module>
part = MIMEText(html, "html")
File "C:\Users\Python\Python310\lib\email\mime\text.py", line 34, in __init
__
_text.encode('us-ascii')
AttributeError: module 'html' has no attribute 'encode'