Commit a0e66a11 authored by Kazuhiko Shiozaki's avatar Kazuhiko Shiozaki

* add functional automation suite

  * no real display needed because firefox will run on Xvfb
    (please install the x11-server-xvfb package)
  * Xvfb (and firefox on it) will be killed when functional tests finish.

Usage:

  # prepare zope instance for functional tests
  $ ./runUnitTest.py --save prepareFunctionalTest.py

  # invoke firefox on Xvfb and send results by email.
  $ ./runFunctionalTest.py



git-svn-id: https://svn.erp5.org/repos/public/erp5/trunk@12599 20353a03-c40f-0410-a6d1-a30d3c3de9de
parent fe4bbe67
// Don't ask if we want to switch default browsers
user_pref("browser.shell.checkDefaultBrowser", false);
// Disable pop-up blocking
user_pref("browser.allowpopups", true);
user_pref("dom.disable_open_during_load", false);
// Configure us as the local proxy
//user_pref("network.proxy.type", 2);
// Disable security warnings
user_pref("security.warn_submit_insecure", false);
user_pref("security.warn_submit_insecure.show_once", false);
user_pref("security.warn_entering_secure", false);
user_pref("security.warn_entering_secure.show_once", false);
user_pref("security.warn_entering_weak", false);
user_pref("security.warn_entering_weak.show_once", false);
user_pref("security.warn_leaving_secure", false);
user_pref("security.warn_leaving_secure.show_once", false);
user_pref("security.warn_viewing_mixed", false);
user_pref("security.warn_viewing_mixed.show_once", false);
// Disable "do you want to remember this password?"
user_pref("signon.rememberSignons", false);
##############################################################################
#
# Copyright (c) 2007 Nexedi SARL and Contributors. All Rights Reserved.
# Kazuhiko <kazuhiko@nexedi.com>
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
#
# Prepare ERP5 Zelenium Test.
#
# usage: python runUnitTest.py --save [OPTION]... prepareFunctionalTest.py
#
import os
import sys
from time import sleep
if __name__ == '__main__':
execfile(os.path.join(sys.path[0], 'framework.py'))
# Needed in order to have a log file inside the current folder
os.environ['EVENT_LOG_FILE'] = os.path.join(os.getcwd(), 'zLOG.log')
os.environ['EVENT_LOG_SEVERITY'] = '-300'
from Products.ERP5Type.tests.ERP5TypeTestCase import ERP5TypeTestCase
os.environ['erp5_tests_portal_id'] = 'erp5_portal'
class TestZelenium(ERP5TypeTestCase):
def getBusinessTemplateList(self):
"""
Return the list of business templates.
"""
return ('erp5_base', 'erp5_ui_test', 'erp5_forge',
'erp5_trade', 'erp5_pdm', 'erp5_pdf_style',
'erp5_accounting', 'erp5_accounting_ui_test',
# 'erp5_accounting_l10n_fr', 'erp5_payroll',
# 'erp5_payroll_ui_test',
)
def testInformation(self):
self.assert_(False, 'This script is intended to be used with --save option.')
if __name__ == '__main__':
framework()
else:
import unittest
def test_suite():
suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestZelenium))
return suite
#!/usr/bin/env python
import os
import re
import signal
from time import sleep
import urllib2
from subprocess import Popen, PIPE
from sendMail import sendMail
import pysvn
host = 'localhost'
port = 8080
portal_name = 'erp5_portal'
instance_home = '/var/lib/zope/unit_test'
profile_dir = '%s/profile' % instance_home
def main():
setPreference()
status = getStatus()
xvfb_pid = None
firefox_pid = None
try:
xvfb_pid = runXvfb()
firefox_pid = runFirefox()
while True:
sleep(10)
cur_status = getStatus()
if status != cur_status:
break
print cur_status
finally:
if xvfb_pid:
os.kill(xvfb_pid, signal.SIGTERM)
if firefox_pid:
os.kill(firefox_pid, signal.SIGTERM)
def startZope():
os.environ['erp5_force_data_fs'] = "1"
os.system('%s/bin/zopectl start' % instance_home)
sleep(2) # ad hoc
def stopZope():
os.system('%s/bin/zopectl stop' % instance_home)
def runXvfb():
pid = os.spawnlp(os.P_NOWAIT, 'Xvfb', 'Xvfb', ':123')
display = os.environ['DISPLAY']
if display:
(displayname, protocolname, hexkey) = Popen(['xauth', 'list', display], stdout=PIPE).communicate()[0].split()
Popen(['xauth', 'add', 'localhost/unix:123', protocolname, hexkey])
print 'Xvfb : %d' % pid
return pid
def prepareFirefox():
os.system("rm -rf %s" % profile_dir)
os.mkdir(profile_dir)
pref = file(os.path.join(os.path.dirname(__file__), 'prefs.js')).read()
pref_file = open(os.path.join(profile_dir, 'prefs.js'), 'w')
pref_file.write(pref)
pref_file.close()
def runFirefox():
os.environ['MOZ_NO_REMOTE'] = '1'
os.environ['DISPLAY'] = ':123'
os.environ['HOME'] = profile_dir
prepareFirefox()
pid = os.spawnlp(os.P_NOWAIT, "firefox", "firefox", "-profile", profile_dir, "http://%s:%d/%s/portal_tests?auto=true&__ac_name=ERP5TypeTestCase&__ac_password=" % (host, port, portal_name))
os.environ['MOZ_NO_REMOTE'] = '0'
print 'firefox : %d' % pid
return pid
def getStatus():
try:
status = urllib2.urlopen('http://%s:%d/%s/TestTool_getResults' % (host, port, portal_name)).read()
except urllib2.HTTPError, e:
if e.msg == "No Content" :
status = ""
else:
raise
return status
def setPreference():
urllib2.urlopen('http://%s:%d/%s/BTZuite_setPreference?__ac_name=ERP5TypeTestCase&__ac_password=' % (host, port, portal_name))
def sendResult():
result_uri = urllib2.urlopen('http://%s:%d/%s/TestTool_getResults' % (host, port, portal_name)).readline()
file_content = urllib2.urlopen(result_uri).read()
passes_re = re.compile('<th[^>]*>Tests passed</th>\n\s*<td[^>]*>([^<]*)')
failures_re = re.compile('<th[^>]*>Tests failed</th>\n\s*<td[^>]*>([^<]*)')
check_re = re.compile('<img[^>]*?/check.gif"\s*[^>]*?>', re.M)
error_re = re.compile('<img[^>]*?/error.gif"\s*[^>]*?>', re.M)
error_title_re = re.compile('error.gif.*?>([^>]*?)</td></tr>', re.S)
passes = passes_re.search(file_content).group(1)
failures = failures_re.search(file_content).group(1)
error_titles = [re.compile('\s+').sub(' ', x).strip() for x in error_title_re.findall(file_content)]
os.chdir('%s/Products/ERP5' % instance_home)
revision = pysvn.Client().info('.').revision.number
subject = "ERP5 r%s: Functional Tests, %s Passes, %s Failures" % (revision, passes, failures)
summary = """
Test Summary
Tests passed: %4s
Tests failed: %4s
Following tests failed:
%s""" % (passes, failures, "\n".join(error_titles))
file_content = check_re.sub('<span style="color: green">PASS</span>', file_content)
file_content = error_re.sub('<span style="color: red">FAIL</span>', file_content)
status = (not failures)
sendMail(subject = subject, body = summary, status = status,
attachments = [file_content])
if __name__ == "__main__":
startZope()
main()
sendResult()
stopZope()
##############################################################################
#
# Copyright (c) 2007 Nexedi SARL and Contributors. All Rights Reserved.
# Kazuhiko <kazuhiko@nexedi.com>
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
"""Send a mail with attachments.
"""
import smtplib
import re
from datetime import date
from email.MIMEText import MIMEText
from email.MIMEBase import MIMEBase
from email.MIMEImage import MIMEImage
from email.MIMEMultipart import MIMEMultipart
from email.Message import Message
def sendMail(subject,
body,
attachments = [],
status = False,
from_mail = 'nobody@erp5.org',
to_mail = [ 'erp5-report@erp5.org' ]):
if attachments:
msg = MIMEMultipart()
else:
msg = Message()
msg['Subject'] = subject
msg['From'] = from_mail
msg['To'] = ', '.join(to_mail)
msg['X-ERP5-Tests'] = 'ERP5'
if status:
msg['X-ERP5-Tests-Status'] = 'OK'
# Guarantees the message ends in a newline
msg.preamble = subject
msg.epilogue = ''
if attachments:
mime_text = MIMEText(body)
mime_text.add_header('Content-Disposition', 'attachment',
filename='body')
msg.attach(mime_text)
html_re = re.compile('<html>', re.I)
for item in attachments:
mime_text = MIMEText(item)
if html_re.match(item):
mime_text.set_type('text/html')
mime_text.add_header('Content-Disposition', 'attachment',
filename='attachment.html')
else:
mime_text.add_header('Content-Disposition', 'attachment',
filename='attachment.txt')
msg.attach(mime_text)
else:
msg.set_payload(body)
# Send the email via our own SMTP server.
s = smtplib.SMTP()
s.connect()
s.sendmail(from_mail, to_mail, msg.as_string())
s.close()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment