精华内容
下载资源
问答
  • PO Box简介

    2016-06-13 15:00:00
    使用Erlang写程序的时候,经常会碰到一种情况:因为Erlang进程的mailbox是没有大小限制的,所以它会一直接受消息,直到Erlang节点内存溢出。在大多数情况下,我们可以...PO Box就是一个可以减轻负载的工具。 设计原...

    使用Erlang写程序的时候,经常会碰到一种情况:因为Erlang进程的mailbox是没有大小限制的,所以它会一直接受消息,直到Erlang节点内存溢出。在大多数情况下,我们可以通过限制消息生产者的频率来解决这个问题,而且也应该实现这一点。但是,有时候不太可能完全限制发给一个进程的所有消息,这时候,开发人员就需要通过丢弃消息来减轻负载。

    PO Box就是一个可以减轻负载的工具。

    设计原则

    PO Box是一个实现了消息缓冲区的功能的库。因为Erlang进程需要同时接收消息并做自身的工作,所以很有可能因为消息过多,而使内存消耗急剧上升。

    这是Erlang现在实现的消息处理逻辑,所有的消息都是放在mailbox中的,当一条消息处理卡顿时,会导致后面的消息一直在排队,消耗内存。

                     messages  
                       |  
                       V  
            +-----[Pid or Name]-----+  
            |      |         |      |  
            |      | mailbox |      |  
            |      +---------+      |  
            |       |               |  
            |    receive            |  
            +-----------------------+  

    PO Box实现了一个消息代理:

                                                             messages  
                                                                |  
                                                                V  
            +---------[Pid]---------+                +--------[POBox]--------+  
            |                       |<-- got mail ---|      |         |      |  
            |                       |                |      | mailbox |      |  
            |   <important stuff>   |--- send it! -->|      +---------+      |  
            |                       |                |       |               |  
            |                       |<---<messages>--|<---buffer             |  
            +-----------------------+                +-----------------------+ 

    可以将一个PO Box进程看成是一个消息代理,它通过实现一个缓冲区,对消息进行缓存,并在缓冲区满了的时候丢弃消息。PO Box可以通知你有新的数据,这样你可以请求这些数据;或者你可以通知它直接把数据发给你,不用通知

    更具体一些,就是PO Box是一个有owner进程的状态机,共有3种状态:

    • Active
    • Notify
    • Passive

    Passive状态基本上除了接收消息保存在缓冲区和必要时丢弃消息,不做什么事。

    用户可以通过调用PO Box的api来进入Notify状态。该状态的唯一任务是检查缓冲区内有没有消息。如果有,它会发一个{mail, new_data}给owner进程。如果没有,PO Box会一直在notify状态等待,直到有新消息。在发送通知后,PO Box会返回passive状态。

    只有active状态可以将真实数据发给owner进程。用户同样可以通过调用PO Box的api告知它进入active状态。如果缓冲区内有消息,所有的消息会以一个list的状态发给owner进程。如果没有消息,PO Box会等待直到有消息。转发完消息后,PO Box会回到passive状态。

                        ,---->[passive]------(user makes active)----->[active]
                        |         | ^                                  |  ^  |
                        |         | '---(sends message to user)--<-----'  |  |
                        |  (user makes notify)                            |  |
                        |         |                                       |  |
               (user is notified) |                                       |  |
                        |         V                                       |  |
                        '-----[notify]---------(user makes active)--------'  |
                                  ^----------(user makes notify)<----------'

    缓存类型

    PO Box实现了消息的缓存机制,当前支持的缓存方式包括三种:queuestackkeep_old queue

    queue按消息到达的顺序保存消息,当缓存满时,会丢弃最老的消息。例如,有6条消息,a,b,c,d,e,消息缓存的大小是3,最后会保留的消息是[c, d, e]。

    keep_old queue也是一种queue,不过当缓存满时,会阻止新的消息的到达。例如,有6条消息,a,b,c,d,e,缓存大小是3,最后会保留的消息是[a, b, c]。

    stack并不能保证消息的顺序呢。当缓存满时,会丢弃栈顶的消息。对于前面两个例子,stack最后保存的消息是[e, b, a]。

    当考虑采取哪一种缓存类型时,要关注的地方是:

    • 是否需要消息保持有序
    • 是保留最新到达的消息,还是最先到达的消息
    • 对时间上有没有要求?如果要求最低的时间延迟,选择stack。

    当然,也可以自己开发自己想要的缓存类型。


    使用用例

    PO Box进程启动函数:

        start_link(OwnerPid, MaxSize, BufferType)      
        start_link(OwnerPid, MaxSize, BufferType, InitialState)    
        start_link(Name, OwnerPid, MaxSize, BufferType)  
        start_link(Name, OwnerPid, MaxSize, BufferType, InitialState) 
    • Name 就是Po Box进程注册的名字
    • OwnerPid 就是PO Box的owner进程的Pid。只有owner进程可以读取该PO Box进程的消息,也只有这个owner进程可以设置PO Box进程的state。OwnerPid也可以是原子。两个进程之间会建立link关系,PO Box 不会trap exits。所以如果想要PO Box进程独立存活,应该手动取消link。
    • MaxSize 就是缓冲区的大小
    • BufferType 就是上面所说缓存类型
    • InitialState 可以是passive或者notify。缺省是notify

    将PO Box转入active状态

        pobox:active(BoxPid, FilterFun, FilterState)

    FilterFun就是消息的读取过滤函数,返回值如下:

    • ok, Message, NewState 这条消息会被发送到owner进程
    • {drop, NewState} 这条消息会被丢弃
    • skip 这条消息会被留在缓冲区,之前被遍历过的会被发送

    消息发送的格式是:

    {mail, BoxPid, Messages, MessageCount, MessageDropCount}

    转换成notify状态:

    pobox:notify(BoxPid)

    发送消息:

    pobox:post(BoxPid, Msg)

    或者

    BoxPid ! {post, Msg}    

    注意

    • FilterFun必须是轻量级,尤其是在处理消息到达速度非常快的时候。因为发送到PO Box进程的消息还是会先保存在Po Box自己的Mailbox中.
    • 一个进程可以有多个PO Box进程
    • 可以看到,如果使用keep_old queue类型,一次处理一条消息,等价于拥有一个受限制的mailbox。

    FilterFun/2

    FilterFun/2的两个参数是message和state。

    会把所有消息都发送到owner进程的函数可以这样写

    fun(Msg, _ ) -> {{ok, Msg}, nostate} 
        end.

    限制二进制消息大小的函数可以这样写:

    fun(Msg, Allowed) ->  
        case Allowed - byte_size(Msg) of  
            N when N < 0 -> skip;  
            N -> {{ok, Msg}, N}  
        end  
    end

    丢掉空消息:

    fun(<<>>, State) -> {drop, State};  
        (Msg, State) -> {{ok, Msg}, State}  
    end.

    只读取一条消息:

    fun(Msg, 0) -> {{ok, Msg}, 1};
        (_, _) -> skip  
    end.

    转载于:https://www.cnblogs.com/xianzhedeyu/p/5580647.html

    展开全文
  • Squeezebox 服务器插件。 处理服务器端文件类型转换和重采样。 替换 custom-convert.conf。 最好与 Squeezelite-r2 (https://github.com/marcoc1712/squeezelite) 作为播放器一起使用,以便在服务器端对 PCM 进行上...
  • PO / PO tutorial

    2021-03-31 16:48:09
    Next, the message engine published the message to message box.The message box is a mircosort SQL table containing message to be processed. 6. The messaging engine sends the message to either the ...

    What is SAP PI ?

    PI ( Process Integration ) is an enterprise integration platform that provides seamless integration between SAP and non-SAP applications within the organization A2A ( Application to Application ) or even outside the organization B2B ( Business to Business ). It allows organizations to exchange information between internal software within the company and external systems outside the company.

    What is SAP PO ?

    PO ( Process  Orchestration ) is a tool for automation and optimization of business processes. It combines the features of SAP Business Process Management (BPM) ,SAP Process Integration (PI)  and SAP Business Rules Management ( BRM ).In other words, SAP process orchestration is a more advanced version or SAP PI and has all the tools required to integrate applications.

    Prior to SAP PI, business would connect with each other through point-to-point communication. But this process is not  used for multiple and complex processes. For smooth communication between multiple businesses, mediated communication or integration broker is used, and SAP PI adopts this very well. It enables interconnection of diffirent process via a central location knows as integration broker, unlike point to point connection which is more like a spider web. The integration broker or server is an integral part of mediated communication consist of Java based Advanced Adapter Engine (AAE) and an integration engine for routing.Mediated communication is based on an integration broker which is executed by exchanging XML messages.

    Let see how SAP PI handles the XML messages by the help of Integration Broker. The exchange of data or message in SAP PI occurs in this four phases.

    • Message Transformation : During message exchange , it transforms the structure of the business data.
    • Message Routing : Forwarding one message sent by sender system to one  or more receiver systems
    • Connectivety Adapters : Connecting the integration broker and the receiver system, the adapter will transform the incoming message into an inbound message and later convert it to  the format of the receiving system at the other end
    • Integration Processes : Cross component Business Process Management  consists of function of advanced service orchestration.

    How SAP PO / PI work ?

    SAP PI perform three basic function :

    • Connect : SAP PI has an ability to integrate with all application regardless of weather it is an application from third-party or from SAP,It uses the adapter framework to integrate 3rd party solutions.
    • Co-ordinate : It can define a path / workflow for each business transaction that is integrated.
    • Communication : It can translate files into any format wheather an internal files format or any business to business integration standard  .

    SAP PI is not a single component responsible for the integration of SAP and Non- SAP application, but it is a cluster of components that together make SAP PI functional. This architecture of SAP PI or components is used during design time, configuration time and at run time. The various components of SAP PI include

    System Landscape Directory:
    It is a central information provider in a system landscape. SLD contains two types of information, "Component Information (Installable & Installed) and Landscape description."

    Integration Builder:
    It is a tool-set which contains a set of tools for accessing and editing integration objects

    Integration Repository:
    To develop, design and maintain data types, message structures, mappings, interfaces, integration processes and integration scenarios independently of system landscape, integration repository is used.

    Integration Server:
    It is a central processing engine of the PI. All messages are processed using this server.

    Central Monitoring:
    With the help of this monitoring of PI domain is done, and "workbench" is the tool that is used for monitoring.

    Adapter Engine:
    It acts as a connector to connect the integration engine to SAP systems and other systems.

    Message Processing Technique by PI:
    To access data from SAP and Non-SAP application this technique is used. SAP PI uses an intermediate document like IDoc to Flat files to transfer their data.

    Design:
    Process Integration (PI) uses integration repository to design message structure

    Configuration:
    Integration Directory (ID) is used to configure technical parameters for objects created in IR ( Integration Repository)

    Message Processing:
    Once the IDOC is activated in SAP system, PI takes in charge and convert messages into XML format for its internal processing

    Message Monitoring:
    The messages can be monitored and traced using "Run Time Workbench". This tool can be useful in monitoring sender and receiver adapters, Outgoing and Incoming messages, End to End monitoring of complete scenario and error traces.

    Connectivity : Proxy Framework & Adapter Framework 

    Adapter Framework : 

    SAP PI connects with any external systems( SAP and non-SAP ) using adapter framework. The adapter framework is based on the  AS jave envioranment and the connector architecture (JCA) version. The adapter framework consists of two default module chains , if message processing is executed entrily within the adapter, the default module chains for the adapter can ben used .

    1. One for the sender direction.

    2. Two for the receiver direction.

    There are four types of adapters for SAP PI .

    • file adapter : It exchanges files with extermal systems.
    • JMS adapter : It communicates with a messaging system.
    • SOAP adapter : It communicates with the providers and clients of  web services.
    • JDBC adapter : It is an external pack of SAP PI.

    Others interfaces supposed by adapter framework are : 

    1. Configuration Services ( API and Adapter metadata xsd)
    2. Administration Services
    3. Various service APIs provided by Adapter framework- Thread Manager, Transaction Manager)
    4. Adapter framework includes a message audit log API. The API can be used for the technical trace and logging to write trace statements that describes the execution of the code.

    How adapter framework works?

    1. The data is received from the wire through a location that is listening for message at certain protocol at a specified address.

    2.  After the message is received by the receive location , a message is sent to the adapter. It creates a new Biztalk message, attaches the data stream to the message.

    3. It adds any meta-data pertaining to the end-point over which the data was received and then the message is submitted to the message engine.

    4. Message engine sends message to the receive pipeline where the data is transformed into XML, here the message sender is authenticated, a message is decrypted and the XML is validated.

    5. Next, the message engine published the message to message box.The message box is a mircosort SQL table containing message to be processed.

    6. The messaging engine sends the message to either the orchistration or send port.

    SAP PI/PO Secutiry 

    For messages , SAP PI provides the message level security for XI message protocol, for the SOAP adapter, for the RosettaNet protocol, for mail adapter, for the CIDX protocol and for the connectivity with WSRM ( Web Service Reliable Messaging ) enabled systems.In SAP PI message level security enabled through the use of encryption, digital signature, SAML Assertion, Username token, etc.Authentication methods supported by WS infrastructure for transport level includes basic authentication ( Password and Username ), SAP assertion ticket , and HTTP over SSL.

    Connecting integration server with WSRM ( Web Service Reliable Messaging ) enable System . 

    To connect with WSRM enable system you see use a communivation  channel of adapter of WS,

    • You use a sender agreement with an assigned WS sender adapter to connect the Integration Server to a WS consumer
    • You use a receiver agreement with an assigned WS receiver adapter to connect the integration server to a WS provider

    Benefits of SAP PI/PO

    • Permission of the receiver application are checked against the original user.
    • In the receiver system, a user can be audited.
    • Dynamic configuration at PI receiver channel.

    NEW Feature in PI/PO

    The new features in SAP PI include

    • Centralized monitoring based on SAP solution manager.
    • Very large (binary) file to file transfer
    • IDOC ( Intermediate Document ) and HTTP adapters in AAE (Advance Adapter Engine)
    • User Centric perspective in the ESR
    • Interface and Mapping based message split on AAE
    • Time Out configuration per communication channel
    • Automated Transport for Schema Validation
    • Replacing Trex, user-defined message search
    • User Centric perspectives in the ESR
    • Add-on for SAP PI: Secure Connectivity add-on (SGTP Adapter, PGP module) & B2B add-ons (OFTP adapter, AS2 adapter, EDI separator, EDI XML converter etc.)

    Advantages of SAP PI/PO

    • In comparison to any other middleware product monitoring in SAP PI is better. It offers monitoring features like a message, performance, component monitoring and so on, all of which can be used to track and rectify the errors.
    • SAP PI supports various SAP components which are required while integrating with SAP PI
    • Adapters and mappings are good as compared with any other middleware product
    • Asynchronous and Synchronous comminication is prossible

    When SAP PI/PO is not recommended in enterprise SOA (Service Oriented Architecture)


    SAP PI is not recommended for synchronous communication as it will put a significant load on the infrastructure service for servicing asynchronous request
    SAP PI is not recommended for UI driven scenarios if the backend is exposed as enterprise services
    SAP PI is not needed for intermediation if a non-SAP backend like J2EE or .NET platform is exposing business services in a UI scenario

    https://blog.csdn.net/XLevon/article/details/111561414

     

    展开全文
  • 整理一下 selenium 自动化测试实践中使用较多的 PO(PageObject)设计模式面向对象的特性:封装\继承\多态.在自动化中一样适用,selenium 自动化测试中有一个名字常常被提及 PageObject(思想与面向对象的特性相同),通过 ...

    整理一下 selenium 自动化测试实践中使用较多的 PO(PageObject)设计模式

    面向对象的特性:封装\继承\多态.在自动化中一样适用,selenium 自动化测试中有一个名字常常被提及 PageObject(思想与面向对象的特性相同),通过 PO 模式可以大大提高测试用例的维护效率

    传统测试脚本的弊端:

    测试脚本分离,维护成本高

    可扩展性差

    复用性低等

    PageObject 设计模式

    selenium 自动化测试框架 PO 设计模式

    PO 的核心要素:

    在 PO 模式中抽象封装成一个BasePage 类,该基累应该拥有一个只实现 webdriver 实例的属性.

    每个一个 page 都继承 BasePage,通过 driver 来管理本 page 中元素,讲 page 中的操作封装成一个个的方法.

    TestCase 继承 unittest.Testcase 类,并且依赖 page 类,从而实现相应的测试步骤.

    例:

    1.页面元素(登录页面)

    from selenium.webdriver.common.by import By

    class loginPageLocator:

    # 用户名输入框

    user_input = (By.XPATH,'//input[@name="username"]')

    # 密码输入框

    passwd_input = (By.XPATH,'//input[@name="password"]')

    # 登录按钮

    login_button = (By.XPATH,'//button[@class="el-button el-button--primary"]')

    # 错误提示 - 登录表单区域

    form_error_info = (By.XPATH,'//div[@class="el-form-item__error"]')

    # 登录页弹框 - 标题

    login_box_title = (By.XPATH,'//span[text()="确定登出"]')

    # 登录页弹框 - 文本

    login_box_text = (By.XPATH,'//p[text()="你已被登出,可以取消继续留在该页面,或者重新登录"]')

    # 登录页弹框 - 重新登录

    login_box_relog = (By.XPATH,'//button[@class="el-button el-button--default el-button--small el-button--primary "]')

    # 登录页弹框 - 取消

    login_box_cancel = (By.XPATH,'//button[@class="el-button el-button--default el-button--small"]')

    # 登录页弹框 - 关闭

    login_box_close = (By.XPATH,'//i[@class="el-message-box__close el-icon-close"]')

    2.页面元素(首页)

    from selenium.webdriver.common.by import By

    class indexPageLocator:

    # 右上角用户名

    user_link = (By.XPATH,'//li[@class="logout"]')

    3.关键字封装(基础操作)

    """

    1.生成执行日志;测试用例的执行日志

    2.测试用例的任何一行代码失败,都希望能在日志当中看到异常信息,并且生成失败的网页截图

    3.精简一下我的 pageobjects 页面

    测试用例 = 页面对象(步骤+断言) + 测试数据

    页面对象 = 页面行为 + 页面元素定位

    页面行为 = selenium webdrive基本 API{查找元素\等待\点击\输入\清除\文本获取\属性获取}组合起来的

    对 WebDrive 的基础函数封装一下.加入日志\异常处理\失败截图

    BasePage 具备以上三点

    """

    from selenium.webdriver.support.wait import WebDriverWait

    from selenium.webdriver.support import expected_conditions as EC

    import logging,time,datetime

    from Common import file_path

    from Common.testLogging import MyLog

    class basePage:

    def __init__(self,driver):

    self.driver = driver

    # 等待元素可见

    def wait_eleVisible(self,loc,timeout=20,poll_frequency=0.5,model=None):

    """

    :param loc:元素定位表达;元组类型,表达方式(元素定位类型,元素定位方法)

    :param timeout:等待的上限

    :param poll_frequency:轮询频率

    :param model:等待失败时,截图操作,图片文件中需要表达的功能标注

    :return:None

    """

    logging.info('{} 等待元素可见:{}'.format(model,loc))

    try:

    start = time.time()

    WebDriverWait(self.driver,timeout,poll_frequency).until(EC.visibility_of_element_located(loc))

    end = time.time()

    MyLog().logger().info('等待时长:%.2f 秒'%(end - start))

    except:

    MyLog().logger().exception('{} 等待元素可见失败:{}'.format(model,loc))

    # 截图

    self.save_webImgs(model)

    raise

    # 等待元素不可见

    def wait_eleNoVisible(self,loc,timeout=20,poll_frequency=0.5,model=None):

    """

    :param loc:元素定位表达;元组类型,表达方式(元素定位类型,元素定位方法)

    :param timeout:等待的上限

    :param poll_frequency:轮询频率

    :param model:等待失败时,截图操作,图片文件中需要表达的功能标注

    :return:None

    """

    logging.info('{} 等待元素不可见:{}'.format(model,loc))

    try:

    start = time.time()

    WebDriverWait(self.driver,timeout,poll_frequency).until_not(EC.visibility_of_element_located(loc))

    end = time.time()

    MyLog().logger().info('等待时长:%.2f 秒'%(end - start))

    except:

    MyLog().logger().exception('{} 等待元素不可见失败:{}'.format(model,loc))

    # 截图

    self.save_webImgs(model)

    raise

    # 查找一个元素element

    def find_Element(self,loc,model=None):

    MyLog().logger().info('{} 查找元素 {}'.format(model,loc))

    try:

    return self.driver.find_element(*loc)

    except:

    MyLog().logger().exception('查找元素失败.')

    # 截图

    self.save_webImgs(model)

    raise

    # 查找元素elements

    def find_Elements(self,loc,model=None):

    MyLog().logger().info('{} 查找元素 {}'.format(model,loc))

    try:

    return self.driver.find_element(*loc)

    except:

    MyLog().logger().exception('查找元素失败.')

    # 截图

    self.save_webImgs(model)

    raise

    # 输入操作

    def input_Text(self,loc,text,model=None):

    # 查找元素

    ele = self.find_Element(loc,model)

    # 输入操作

    MyLog().logger().info('{} 在元素 {} 中输入文本: {}'.format(model,loc,text))

    try:

    ele.send_keys(text)

    except:

    MyLog().logger().exception('输入操作失败')

    # 截图

    self.save_webImgs(model)

    raise

    # 清除操作

    def clean_Input_Text(self,loc,model=None):

    ele = self.find_Element(loc,model)

    # 清除操作

    MyLog().logger().info('{} 在元素 {} 中清除'.format(model,loc))

    try:

    ele.clear()

    except:

    MyLog().logger().exception('清除操作失败')

    # 截图

    self.save_webImgs(model)

    raise

    # 点击操作

    def click_Element(self,loc,model=None):

    # 先查找元素在点击

    ele = self.find_Element(loc,model)

    # 点击操作

    MyLog().logger().info('{} 在元素 {} 中点击'.format(model,loc))

    try:

    ele.click()

    except:

    MyLog().logger().exception('点击操作失败')

    # 截图

    self.save_webImgs(model)

    raise

    # 获取文本内容

    def get_Text(self,loc,model=None):

    # 先查找元素在获取文本内容

    ele = self.find_Element(loc,model)

    # 获取文本

    MyLog().logger().info('{} 在元素 {} 中获取文本'.format(model,loc))

    try:

    text = ele.text

    MyLog().logger().info('{} 元素 {} 的文本内容为 {}'.format(model,loc,text))

    return text

    except:

    MyLog().logger().exception('获取元素 {} 的文本内容失败,报错信息如下:'.format(loc))

    # 截图

    self.save_webImgs(model)

    raise

    # 获取属性值

    def get_Element_Attribute(self,loc,model=None):

    # 先查找元素在去获取属性值

    ele = self.find_Element(loc,model)

    # 获取元素属性值

    MyLog().logger().info('{} 在元素 {} 中获取属性值'.format(model,loc))

    try:

    ele_attribute = ele.get_attribute()

    MyLog().logger().info('{} 元素 {} 的文本内容为 {}'.format(model, loc, ele_attribute))

    return ele_attribute

    except:

    MyLog().logger().exception('获取元素 {} 的属性值失败,报错信息如下:'.format(loc))

    self.save_webImgs(model)

    raise

    # iframe 切换

    def switch_iframe(self,frame_refer,timeout=20,poll_frequency=0.5,model=None):

    # 等待 iframe 存在

    MyLog().logger().info('iframe 切换操作:')

    try:

    # 切换 == index\name\id\WebElement

    WebDriverWait(self.driver,timeout,poll_frequency).until(EC.frame_to_be_available_and_switch_to_it(frame_refer))

    time.sleep(0.5)

    MyLog().logger().info('切换成功')

    except:

    MyLog().logger().exception('iframe 切换失败!!!')

    # 截图

    self.save_webImgs(model)

    raise

    # 窗口切换 = 如果是切换到新窗口,new. 如果是回到默认的窗口,default

    def switch_window(self,name,cur_handles=None,timeout=20,poll_frequency=0.5,model=None):

    """

    调用之前要获取window_handles

    :param name: new 代表最新打开的一个窗口. default 代表第一个窗口. 其他的值表示为窗口的 handles

    :param cur_handles:

    :param timeout:等待的上限

    :param poll_frequency:轮询频率

    :param model:等待失败时,截图操作,图片文件中需要表达的功能标注

    :return:

    """

    try:

    if name == 'new':

    if cur_handles is not None:

    MyLog().logger().info('切换到最新打开的窗口')

    WebDriverWait(self.driver,timeout,poll_frequency).until(EC.new_window_is_opened(cur_handles))

    window_handles = self.driver.window_handles

    self.driver.swich_to.window(window_handles[-1])

    else:

    MyLog().logger().exception('切换失败,没有要切换窗口的信息!!!')

    self.save_webImgs(model)

    raise

    elif name == 'default':

    MyLog().logger().info('切换到默认页面')

    self.driver.switch_to.default()

    else:

    MyLog().logger().info('切换到为 handles 的窗口')

    self.driver.swich_to.window(name)

    except:

    MyLog().logger().exception('切换窗口失败!!!')

    # 截图

    self.save_webImgs(model)

    raise

    # 截图

    def save_webImgs(self,model=None):

    # filepath = 指图片保存目录/model(页面功能名称)_当前时间到秒.png

    # 当前时间

    dateNow = str(datetime.datetime.now()).split('.')[0]

    # 路径

    filePath = '{}/{}_{}.png'.format(file_path.image_path,model,dateNow)

    try:

    self.driver.save_screenshot(filePath)

    MyLog().logger().info('截屏成功,图片路径为{}'.format(filePath))

    except:

    MyLog().logger().exception('截屏失败!')

    4.页面操作脚本

    from pageLocator.loginPage_locator import loginPageLocator as loc

    from Common.BasePage import basePage

    class LoginPage(basePage):

    # 登录操作

    def login(self,username,passwd):

    # 等待用户名文本框元素出现

    self.wait_eleVisible(loc.user_input,model='等待用户名文本框元素出现')

    # 清除文本框内容

    self.clean_Input_Text(loc.user_input,model='清除用户名文本框内容')

    # 输入用户名

    self.input_Text(loc.user_input,text=username,model='输入用户名')

    # 等待密码文本框元素出现

    self.wait_eleVisible(loc.passwd_input,model='等待密码文本框元素出现')

    # 清除密码文本框内容

    self.clean_Input_Text(loc.passwd_input,model='清除密码文本框内容')

    # 输入密码

    self.input_Text(loc.passwd_input,text=passwd,model='输入密码')

    # 点击登录按钮

    self.click_Element(loc.login_button,model='点击登录按钮')

    # 获取页面错误提示 - 登录表单区域

    def get_wrongMsg_byForm(self):

    # 等待表单文本提示元素出现

    self.wait_eleVisible(loc.form_error_info,model='等待表单文本提示元素出现')

    return self.get_Text(loc.form_error_info,model='获取表单文本提示内容')

    def get_boxMsg(self):

    # 等待提示弹框出现

    self.wait_eleVisible(loc.login_box_text,model='等待提示弹框文本内容')

    return self.get_Text(loc.login_box_text,model='获取提示框文本内容')

    将上面的脚本放在 login_page.py 中

    5.因为是测试登录,所以写个登录成功跳转到首页获取其中一个标志元素

    # 查看用户名这个元素

    def is_user_link_exists(self):

    """

    如果存在返回True,如果不存在返回False

    :return

    """

    try:

    WebDriverWait(self.driver,20).until(EC.visibility_of_element_located(loc.user_link))

    return True

    except:

    return False

    6.创建一个 py 以放于公共数据,现在公共数据中只放了 URL

    7.把测试数据写到一个 login_datas.py 中

    # 正常场景 - 登录成功

    login_success_data = {"user":"test","passwd":"123456"}

    # 异常场景 - 用户名为空\用户名密码为空\密码为空

    wrong_data = [

    {"user":"","passwd":"123456","check":"请输入大于5位的用户名"},

    {"user":"","passwd":"","check":"请输入大于5位的用户名"},

    {"user":"test","passwd":"","check":"密码不能小于5位"}

    ]

    # 异常场景 - 错误的用户名\错误的密码

    error_userOrPasswd = [

    {"user":"tes","passwd":"123456","check":"你已被登出,可以取消继续留在该页面,或者重新登录"},

    {"user":"test","passwd":"1234567","check":"你已被登出,可以取消继续留在该页面,或者重新登录"}

    ]

    8.编写测试用例:

    import unittest

    from selenium import webdriver

    from pageObjects.login_page import LoginPage

    from pageObjects.index_page import IndexPage

    from testDatas import common_datas as cd

    from testDatas import login_datas as ld

    from ddt import ddt,data

    @ddt

    class TestLogin(unittest.TestCase):

    def setUp(self):

    # 打开浏览器,访问登录页面

    self.driver = webdriver.Chrome()

    self.driver.maximize_window()

    self.driver.get(cd.web_url)

    self.LP = LoginPage(self.driver)

    def tearDown(self):

    self.driver.quit()

    # 正常场景:登录成功

    def test_login_success(self):

    # 步骤 测试数据:sporttest/123456

    # 登录页面 - 登录功能 - 输入用户名和密码

    self.LP.login(ld.login_success_data['user'],ld.login_success_data['passwd'])

    # 断言

    self.assertTrue(IndexPage(self.driver).is_user_link_exists())

    # 异常场景:用户名为空\用户名密码为空\密码为空

    @data(*ld.wrong_data)

    def test_login_wrongData(self,data):

    # 步骤 测试数据: /123456

    """断言数据:

    请输入大于5位的用户名

    """

    self.LP.login(data['user'],data['passwd'])

    # 断言

    self.assertIn(data['check'],self.LP.get_wrongMsg_byForm())

    # 异常场景:错误的用户名\错误的密码

    @data(*ld.error_userOrPasswd)

    def test_login_errorUserOrPasswd(self,data):

    # 步骤

    self.LP.login(data['user'],data['passwd'])

    # 断言

    self.assertEqual(data['check'],self.LP.get_boxMsg())

    这里在提及一个 setUpClass()和 tearDownClass(),这个是在 setUpClass()开始执行,执行完所有测试用例后再去执行 tearDownClass()

    展开全文
  • Make E-mail Sender of PO the PO Creators Name ABAP Code Needed to Make E-mail Sender of PO the PO Creators Name 1)...
    Make E-mail Sender of PO the PO Creators Name

    ABAP Code Needed to Make E-mail Sender of PO the PO Creators Name

    1) Do the config and user email data setup as noted elsewhere this is supplemental ABAP help ONLY.

    2) Apply OSS note 561593, this is a release independent note.

    3) on SE37, edit function module RV_MESSAGES_MAINTENANCE, this is custom programming logic.

    Look for this context block:

    
     The PO being sent must use the SMTP communication strategy, a 1 in the Number of Messages field, and the Print immediately box checked on. *-- 
     By DF 
     

    Enhancement for sending mail when the purchase order is releaed

    When we release any object in me29n transaction then mail has to be send to vendor that the puchase order has been
    released. The code that is to be written in the enhacement for the same is:

    *&---------------------------------------------------------------------*
    *&  Include           ZXM06U44
    *&---------------------------------------------------------------------*
    *Data Declaration
    DATA : rel_ind LIKE i_ekko-frgke.
    rel_ind = i_ekko-frgke.
    *Release PO when final authorized person process PO
    IF sy-tcode EQ 'ME29N' AND rel_ind EQ 2.
    
    *Internal table to get vendor name and address number
      DATA : BEGIN OF it_vname OCCURS 0,
             name1 LIKE lfa1-name1,
             adrnr LIKE lfa1-adrnr,
             END OF it_vname.
    *Internal table to get email_if with address number
      DATA : BEGIN OF it_vemail OCCURS 0,
             email LIKE adr6-smtp_addr,
             END OF it_vemail.
    *Emiail subject
      DATA : psubject(40) TYPE c .
    
    *Data declaration for mail FM
      DATA:   it_packing_list LIKE sopcklsti1 OCCURS 0 WITH HEADER LINE,
              it_contents LIKE solisti1 OCCURS 0 WITH HEADER LINE,
              it_receivers LIKE somlreci1 OCCURS 0 WITH HEADER LINE,
              it_attachment LIKE solisti1 OCCURS 0 WITH HEADER LINE,
              gd_cnt TYPE i,
              gd_sent_all(1) TYPE c,
              gd_doc_data LIKE sodocchgi1,
              gd_error TYPE sy-subrc.
    
    *Internal table for message body
      DATA:   it_message TYPE STANDARD TABLE OF solisti1 INITIAL SIZE 0
                      WITH HEADER LINE,
              it_messagewa LIKE LINE OF it_message        .
    
      psubject = 'PO Regarding'.
    
    *Accessing name and address number of a vendor
      SELECT SINGLE name1 adrnr FROM lfa1 INTO it_vname WHERE lifnr EQ 
    i_ekko-lifnr.
    
    *Accessing mail id of a vendor
      SELECT SINGLE smtp_addr FROM adr6 INTO it_vemail WHERE addrnumber EQ 
    it_vname-adrnr.
    
    * Mail Text
      clear it_message.
      REFRESH it_message.
      CONCATENATE 'Dear' it_vname-name1 ',' INTO it_messagewa SEPARATED BY 
    space.
      APPEND  it_messagewa TO it_message.
      APPEND 'Please issue the items for the following PO Number .' TO 
    it_message.
      CLEAR it_messagewa.
      CONCATENATE 'PO NUmber : ' i_ekko-ebeln  INTO it_messagewa SEPARATED 
    BY space.
      APPEND it_messagewa TO it_message.
      APPEND 'you can view it at www.mindteck/sap/mm/login.' TO it_message.
      APPEND 'Regards,' TO it_message.
      APPEND 'Anand.' TO it_message.
    
    * Fill the document data.
      gd_doc_data-doc_size = 1.
    
    * Populate the subject/generic message attributes
      gd_doc_data-obj_langu = sy-langu.
      gd_doc_data-obj_name  = 'SAPRPT'.
      gd_doc_data-obj_descr = psubject.
      gd_doc_data-sensitivty = 'F'.
    
    * Describe the body of the message
      CLEAR it_packing_list.
      REFRESH it_packing_list.
      it_packing_list-transf_bin = space.
      it_packing_list-head_start = 1.
      it_packing_list-head_num = 0.
      it_packing_list-body_start = 1.
      DESCRIBE TABLE it_message LINES it_packing_list-body_num.
      it_packing_list-doc_type = 'RAW'.
      APPEND it_packing_list.
    
    * Add the recipients email address
      CLEAR it_receivers.
      REFRESH it_receivers.
      it_receivers-receiver = it_vemail-email.
      it_receivers-rec_type = 'U'.
      it_receivers-com_type = 'INT'.
      it_receivers-notif_del = 'X'.
      it_receivers-notif_ndel = 'X'.
      APPEND it_receivers.
    
    * Call the FM to post the message to SAPMAIL
      CALL FUNCTION 'SO_NEW_DOCUMENT_ATT_SEND_API1'
        EXPORTING
          document_data                    = gd_doc_data
          put_in_outbox                    = 'X'
          commit_work                      = 'X'
       IMPORTING
         sent_to_all                      = gd_sent_all
    *   NEW_OBJECT_ID                    =
        TABLES
          packing_list                     = it_packing_list
    *   OBJECT_HEADER                    =
    *   CONTENTS_BIN                     =
          contents_txt                     = it_message
    *   CONTENTS_HEX                     =
    *   OBJECT_PARA                      =
    *   OBJECT_PARB                      =
          receivers                        = it_receivers
       EXCEPTIONS
         too_many_receivers               = 1
         document_not_sent                = 2
         document_type_not_exist          = 3
         operation_no_authorization       = 4
         parameter_error                  = 5
         x_error                          = 6
         enqueue_error                    = 7
         OTHERS                           = 8
                .
      IF sy-subrc <> 0.
    * MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
    *         WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
      ENDIF.
    
    * Store function module return code
      gd_error = sy-subrc.
    
    * Get it_receivers return code
      LOOP AT it_receivers.
      ENDLOOP.
    ENDIF.
    This we need to write in the mm06e005. In this enhacement in this enhacement there is a function exit exit_sapmm06e_013 in this I had wrote the code for the same enhacement.
    *-- Praveen Kumar (praveen417@gmail.com)[@more@]

    来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/190059/viewspace-1012768/,如需转载,请注明出处,否则将追究法律责任。

    转载于:http://blog.itpub.net/190059/viewspace-1012768/

    展开全文
  • 摘自:http://oraclemaniac.com/2012/08/14/enable-po-approval-process-to-send-po-in-pdf-format-via-email/
  • DOSBOX 安装与使用

    千次阅读 2020-04-21 16:15:16
    DOSBOX安装 Windows 10 64位下 DOS及汇编环境搭建步骤: 1、双击DOSBox0.74-3-win32-installer.exe,按照提示安装在任意目录下。 2、进入步骤1安装的文件夹(DOSBox-0.74-3),双击DOSBox 0.74-3-Options.bat文件,...
  • Epicor New PO Suggestions

    2014-09-03 09:21:32
    New PO Suggestions Use New PO Suggestions to process purchase order (PO) suggestions created by the Gener...
  • Make E-mail Sender of PO the PO Creators Name ABAP Code Needed to Make E-mail Sender of PO the PO Creators Name 1) Do the config and user email data setup as noted elsewhere this is supplemental A
  • Hack The Box 注册教程

    2020-07-13 14:19:53
    Hack The Box 注册破解教程 1.进入https://www.hackthebox.eu/invite 2.进入开发者模式找到 这是压缩过的js,右键点击open in new ... ... 发现makeInviteCode函数 ...在控制台执行makeInviteCode()看响应信息 ...发送一个po
  • PO核准通知界面修改

    2014-08-09 23:14:00
    想在notification頁面把供應商的稅捐代碼帶出來,添在如下紅框中 PO_WF_PO_NOTIFICATION head information:get_po_approve_msg line information:get_po_lines_...CREATE OR REPLACE PACKAGE BODY PO_WF_PO_N...
  • B. Box Fitting

    2021-04-02 19:08:18
    Box Fitting 题意: You are given n rectangles, each of height 1. Each rectangle’s width is a power of 2 (i. e. it can be represented as 2x for some non-negative integer x). You are also given a two...
  • 一 、 PO 是什么 页面对象模型(PO)是一种设计模式,全称(Page Object),用来管理维护一组web元素的对象库 在PO下,应用程序的每一个页面都有一个对应的page class 每一个page class维护着该web页的元素集和...
  • sudo podman stop spark_local_box_1 sudo podman rm spark_local_box_1 sudo podman rmi localhost/spark_local_box sudo podman build -f Dockerfile -t localhost/spark_local_box -m 2g --cpuset-cpus 1,...sudo po
  • 在自动化中一样适用,Selenium自动化测试中有一个名字常常被提及PageObject(思想与面向对象的特性相同),通过PO模式可以大大提高测试用例的维护效率。 ##传统测试脚本的弊端 测试脚本分离,维护成本高 可扩展性差 ...
  • Sears Hackathon提交:-使用区块链的供应链网络 模型 该业务网络定义: ... 资产Commodity Box PO 事务InitiatePO MakeBox TransferBox UnBox TransferCommodity MakeBox UnBox SetupDemo none事件
  • Oracle ERP 之PO部分词汇

    2019-07-10 11:00:08
    Oracle ERP 之PO部分词汇[@more@]词汇表 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z --------------------------...
  • selenium自动化测试框架PO设计模式

    千次阅读 多人点赞 2019-06-21 22:20:54
    整理一下 selenium 自动化测试实践中使用较多的 PO(PageObject)设计模式 面向对象的特性:封装\继承\多态.在自动化中一样适用,selenium 自动化测试中有一个名字常常被提及 PageObject(思想与面向对象的特性相同),...
  • 什么是PO模式 为什么使用PO设计模式 分层思想 实现示例 基于PO模式对代码进行封装 简介 什么是PO模式 Page Object Model,是一种设计模式,提供了一种业务流程与页面元素操作分离的模式。当页面元素发生变化...
  • virualbox andirodx86

    2013-12-27 13:45:00
    virualbox andirodx86 背景 谷歌提供的andriod sdk模拟器在windows平台上很卡,是因为sdk是针对arm处理器架构的(就是嵌入式),而我们的windows系统是 x86架构 或者是 AMD架构,所以安卓模拟器每...
  • 读The CSS Box Model有感

    2015-07-14 20:41:04
    读The CSS Box Model有感 http://my.oschina.net/limichange/blog/72992 看到网上有一篇深入理解盒模型的文章,也想自己动手写一下自己的理解,但是本人菜鸟一枚,所写的东西也是记录自己的历程,不喜...1. 没有po
  • po一个爬虫项目

    2020-07-22 10:16:02
    import com.baosight.po.DriverPo; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.openqa.selenium.By; import org.openqa.selenium.Dimension; import org.openqa....
  • dosbox使用指南

    千次阅读 2020-04-13 16:49:19
    ZR(1) zero NZ(0) no zero 辅助标志AF(Auxiliary carry flag) AC(1) auxiliary carry NA(0) no auxiliary 奇偶标志PF(Parity flag) PE(1) parity even PO(0) parity odd 中断标志IF(Interrupt flag) EI(1) enable ...
  • box2d 粗略的模拟水浮力
  • ShoeBox图片剪辑软件

    2019-03-28 12:32:49
    该款软件具有对png图片进行剪裁等功能,方便游戏场景等开发,配上PS软件使用,好上加好~
  • ** HackTheBox-windows-Heist-Walkthrough ** 靶机地址:https://www.hackthebox.eu/home/machines/profile/180 靶机难度:中级(4.4/10) ...Heist is an easy difficulty Windows box with an “Issues” po...
  • 错误信息为:对于公司间库存转移,禁用“将货品成本用作转移成本”首选项。...Choose the default setting for the Use Item Cost as Transfer Cost box on transfer orders. 为转移订单上"使用物料成本作为转移...
  • PO模式设计之basepage封装

    千次阅读 2020-05-04 17:55:42
    logger.info('浏览器刷新') def get_title(self, title): value = self.driver.title.text logger.info('获取元素名称:%s' % value) '''self.username_input_box = {'element_name': '用户名输入框','locator_type':...
  • PO 审批及生成xml文件

    2019-09-22 09:47:21
    DATA:IT_PO TYPE STANDARD TABLE OF TY_PO WITH HEADER LINE, WA_PO LIKE IT_PO. DATA:TMP_EBELN LIKE EKKO-EBELN. TYPES:BEGIN OF TY_HEAD, LIFNR LIKE EKKO-LIFNR,"SAP廠商編號 NAME1 LIKE LFA1-NAME1,"廠商簡...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,800
精华内容 1,520
关键字:

boxpo